bsw@0: #!/usr/bin/env node bsw@0: bsw@0: // -------------------------------------------------------------------------- bsw@0: // end of configuration bsw@0: // ========================================================================== bsw@0: bsw@0: var main = require('./lfapi/main.js'); bsw@0: bsw@0: var config = main.config; bsw@0: var db = main.db; bsw@0: bsw@0: //var config = require('./config.js'); bsw@0: bsw@0: var http = require('http'); bsw@0: var url = require('url'); bsw@0: var qs = require('querystring'); bsw@0: bsw@0: // Add includes method to Arrays bsw@0: Array.prototype.includes = function (val) { bsw@0: for (var i=0; i < this.length; i++) if (this[i] === val) return true; bsw@0: return false; bsw@0: }; bsw@0: bsw@0: // Member sessions, stored value is member_id bsw@0: var sessions = { }; bsw@0: bsw@0: // create http server bsw@0: var server = http.createServer(function (req, res, params) { bsw@0: req.setEncoding('utf8'); bsw@0: bsw@0: // parse get params bsw@0: var url_info = url.parse(req.url, true); bsw@0: var params = url_info.query; bsw@0: req.params = params; bsw@0: bsw@0: req.current_access_level = config.public_access_level; bsw@0: req.current_member_id; bsw@0: bsw@0: req.sessions = sessions; bsw@0: bsw@0: // session handling bsw@0: if (params.session_key) { bsw@0: if (sessions[params.session_key]) { bsw@0: req.current_member_id = sessions[params.session_key]; bsw@0: req.current_access_level = 'member' bsw@0: } else { bsw@0: main.respond('json', null, req, res, 'forbidden', 'Invalid session key'); bsw@0: } bsw@0: } bsw@0: bsw@0: // pick cookies from http headers bsw@0: var cookies = {}; bsw@0: if (req.headers.cookie) { bsw@0: req.headers.cookie.split(';').forEach(function (cookie) { bsw@0: var parts = cookie.split('='); bsw@0: cookies[parts[0].trim()] = (parts[1] || '' ).trim(); bsw@0: }); bsw@0: }; bsw@0: bsw@0: console.log(req.socket._idleStart, req.socket.remoteAddress, req.current_member_id, req.current_access_level, url_info.pathname, url_info.query); bsw@0: bsw@0: var body = ''; bsw@0: req.on('data', function (data) { bsw@0: body += data; bsw@0: }); bsw@0: req.on('end', function () { bsw@0: var post_params = qs.parse(body); bsw@0: for (key in post_params) { bsw@0: params[key] = post_params[key]; bsw@0: }; bsw@0: bsw@0: if (['POST', 'DELETE'].includes(params.http_method)) { bsw@0: req.method = params.http_method; bsw@0: } bsw@0: bsw@0: var routes; bsw@0: bsw@0: switch(req.method) { bsw@0: case 'GET': bsw@0: routes = main.get; bsw@0: break; bsw@0: bsw@0: case 'DELETE': bsw@0: // delete requests are handled like post request with parameter delete=1 bsw@0: params.delete = '1'; bsw@0: bsw@0: case 'POST': bsw@0: routes = main.post; bsw@0: break; bsw@0: bsw@0: default: bsw@0: main.respond('json', null, req, res, 'not found'); bsw@0: break; bsw@0: bsw@0: }; bsw@0: bsw@0: // dispatch request based on method and url bsw@0: bsw@0: var routing_target = routes[url_info.pathname] bsw@0: if (routing_target) { bsw@0: db.query(config.connectionString, req, res, 'START TRANSACTION ISOLATION LEVEL READ COMMITTED READ WRITE', function (result, conn) { bsw@0: routing_target.apply(this, [conn, req, res, params]); bsw@0: }); bsw@0: } else { bsw@0: main.respond('json', null, req, res, 'not found'); bsw@0: }; bsw@0: bsw@0: }); bsw@0: bsw@0: // actually connect the http server to a network interface bsw@0: }).listen(config.bind_port, config.bind_address); bsw@0: bsw@0: console.log('LiquidFeedback API server started with ' + config.public_access_level + ' public access at ' + config.bind_address + ':' + config.bind_port); bsw@0: bsw@0: bsw@0: