123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- var app = require('http').createServer(handler)
- , sockets = require('./sockets.js')
- , log = require("./log.js").log
- , path = require('path')
- , url = require('url')
- , fs = require("fs")
- , nodestatic = require("node-static")
- , createSVG = require("./createSVG.js")
- , handlebars = require("handlebars");
-
-
- var io = sockets.start(app);
-
- /**
- * Folder from which static files will be served
- * @const
- * @type {string}
- */
- var WEBROOT = path.join(__dirname, "../client-data");
-
- /**
- * Port on which the application will listen
- * @const
- * @type {number}
- */
- var PORT = parseInt(process.env['PORT']) || 8080;
-
- app.listen(PORT);
- log("server started", { port: PORT });
-
- var CSP = "default-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss:";
-
- var fileserver = new nodestatic.Server(WEBROOT, {
- "headers": {
- "X-UA-Compatible": "IE=Edge",
- "Content-Security-Policy": CSP,
- }
- });
-
- function serveError(request, response, err) {
- console.warn("Error serving '" + request.url + "' : " + err.status + " " + err.message);
- fileserver.serveFile('error.html', err.status, {}, request, response);
- }
-
- function logRequest(request) {
- log('connection', {
- ip: request.connection.remoteAddress,
- original_ip: request.headers['x-forwarded-for'] || request.headers['forwarded'],
- user_agent: request.headers['user-agent'],
- referer: request.headers['referer'],
- language: request.headers['accept-language'],
- url: request.url,
- });
- }
-
- function handler(request, response) {
- try {
- handleRequest(request, response);
- } catch (err) {
- console.trace(err);
- response.writeHead(500, { 'Content-Type': 'text/plain' });
- response.end(err.toString());
- }
- }
-
- function baseUrl(req) {
- var proto = req.headers['X-Forwarded-Proto'] || (req.connection.encrypted ? 'https' : 'http');
- var host = req.headers['X-Forwarded-Host'] || req.headers.host;
- return proto + '://' + host;
- }
-
- var BOARD_HTML_TEMPLATE = handlebars.compile(
- fs.readFileSync(WEBROOT + '/board.html', { encoding: 'utf8' })
- );
-
- function handleRequest(request, response) {
- var parsedUrl = url.parse(request.url, true);
- var parts = parsedUrl.pathname.split('/');
- if (parts[0] === '') parts.shift();
-
- if (parts[0] === "boards") {
- // "boards" refers to the root directory
- if (parts.length === 1 && parsedUrl.query.board) {
- // '/boards?board=...' This allows html forms to point to boards
- var headers = { Location: 'boards/' + encodeURIComponent(parsedUrl.query.board) };
- response.writeHead(301, headers);
- response.end();
- } else if (parts.length === 2 && request.url.indexOf('.') === -1) {
- // If there is no dot and no directory, parts[1] is the board name
- logRequest(request);
- var board = decodeURIComponent(parts[1]);
- var body = BOARD_HTML_TEMPLATE({
- board: board,
- boardUriComponent: parts[1],
- baseUrl: baseUrl(request)
- });
- var headers = {
- 'Content-Length': Buffer.byteLength(body),
- 'Content-Type': 'text/html'
- };
- response.writeHead(200, headers);
- response.end(body);
- } else { // Else, it's a resource
- request.url = "/" + parts.slice(1).join('/');
- fileserver.serve(request, response, function (err, res) {
- if (err) serveError(request, response, err);
- });
- }
- } else if (parts[0] === "download") {
- var boardName = encodeURIComponent(parts[1]),
- history_file = "../server-data/board-" + boardName + ".json",
- headers = {
- "Content-Type": "application/json",
- "Content-Disposition": 'attachment; filename="' + boardName + '.wbo"'
- };
- var promise = fileserver.serveFile(history_file, 200, headers, request, response);
- promise.on("error", function (err) {
- console.error("Error while downloading history", err);
- response.statusCode = 404;
- response.end("ERROR: Unable to serve history file\n");
- });
- } else if (parts[0] === "preview") {
- var boardName = encodeURIComponent(parts[1]),
- history_file = path.join(__dirname, "..", "server-data", "board-" + boardName + ".json");
- createSVG.renderBoard(history_file, function (err, svg) {
- if (err) {
- response.writeHead(404, { 'Content-Type': 'application/json' });
- response.end(JSON.stringify(err));
- }
- response.writeHead(200, {
- "Content-Type": "image/svg+xml",
- "Content-Security-Policy": CSP,
- 'Content-Length': Buffer.byteLength(svg),
- });
- response.end(svg);
- });
- } else {
- if (parts[0] === '') logRequest(request);
- fileserver.serve(request, response, function (err, res) {
- if (err) {
- logRequest(request);
- serveError(request, response, err);
- }
- });
- }
- }
-
|