| rev | line source | 
| bsw@0 | 1 #!/usr/bin/env node | 
| bsw@0 | 2 | 
| bsw@0 | 3 // -------------------------------------------------------------------------- | 
| bsw@0 | 4 // end of configuration | 
| bsw@0 | 5 // ========================================================================== | 
| bsw@0 | 6 | 
| bsw@0 | 7 var main = require('./lfapi/main.js'); | 
| bsw@0 | 8 | 
| bsw@0 | 9 var config = main.config; | 
| bsw@0 | 10 var db = main.db; | 
| bsw@0 | 11 | 
| bsw@0 | 12 //var config = require('./config.js'); | 
| bsw@0 | 13 | 
| bsw@0 | 14 var http = require('http'); | 
| bsw@0 | 15 var url = require('url'); | 
| bsw@0 | 16 var qs = require('querystring'); | 
| bsw@0 | 17 | 
| bsw@0 | 18 // Add includes method to Arrays | 
| bsw@0 | 19 Array.prototype.includes = function (val) { | 
| bsw@0 | 20   for (var i=0; i < this.length; i++) if (this[i] === val) return true; | 
| bsw@0 | 21   return false; | 
| bsw@0 | 22 }; | 
| bsw@0 | 23 | 
| bsw@0 | 24 // Member sessions, stored value is member_id | 
| bsw@0 | 25 var sessions = { }; | 
| bsw@0 | 26 | 
| bsw@0 | 27 // create http server | 
| bsw@0 | 28 var server = http.createServer(function (req, res, params) { | 
| bsw@0 | 29   req.setEncoding('utf8'); | 
| bsw@0 | 30 | 
| bsw@0 | 31   // parse get params | 
| bsw@0 | 32   var url_info = url.parse(req.url, true); | 
| bsw@0 | 33   var params = url_info.query; | 
| bsw@0 | 34   req.params = params; | 
| bsw@0 | 35 | 
| bsw@0 | 36   req.current_access_level = config.public_access_level; | 
| bsw@0 | 37   req.current_member_id; | 
| bsw@0 | 38 | 
| bsw@0 | 39   req.sessions = sessions; | 
| bsw@0 | 40 | 
| bsw@0 | 41   // session handling | 
| bsw@0 | 42   if (params.session_key) { | 
| bsw@0 | 43     if (sessions[params.session_key]) { | 
| bsw@0 | 44       req.current_member_id = sessions[params.session_key]; | 
| bsw@0 | 45       req.current_access_level = 'member' | 
| bsw@0 | 46     } else { | 
| bsw@0 | 47       main.respond('json', null, req, res, 'forbidden', 'Invalid session key'); | 
| bsw@0 | 48     } | 
| bsw@0 | 49   } | 
| bsw@0 | 50 | 
| bsw@0 | 51   // pick cookies from http headers | 
| bsw@0 | 52   var cookies = {}; | 
| bsw@0 | 53   if (req.headers.cookie) { | 
| bsw@0 | 54     req.headers.cookie.split(';').forEach(function (cookie) { | 
| bsw@0 | 55       var parts = cookie.split('='); | 
| bsw@0 | 56       cookies[parts[0].trim()] = (parts[1] || '' ).trim(); | 
| bsw@0 | 57     }); | 
| bsw@0 | 58   }; | 
| bsw@0 | 59 | 
| bsw@0 | 60   console.log(req.socket._idleStart, req.socket.remoteAddress, req.current_member_id, req.current_access_level, url_info.pathname, url_info.query); | 
| bsw@0 | 61 | 
| bsw@0 | 62   var body = ''; | 
| bsw@0 | 63   req.on('data', function (data) { | 
| bsw@0 | 64       body += data; | 
| bsw@0 | 65   }); | 
| bsw@0 | 66   req.on('end', function () { | 
| bsw@0 | 67     var post_params = qs.parse(body); | 
| bsw@0 | 68     for (key in post_params) { | 
| bsw@0 | 69       params[key] = post_params[key]; | 
| bsw@0 | 70     }; | 
| bsw@0 | 71 | 
| bsw@0 | 72     if (['POST', 'DELETE'].includes(params.http_method)) { | 
| bsw@0 | 73       req.method = params.http_method; | 
| bsw@0 | 74     } | 
| bsw@0 | 75 | 
| bsw@0 | 76     var routes; | 
| bsw@0 | 77 | 
| bsw@0 | 78     switch(req.method) { | 
| bsw@0 | 79       case 'GET': | 
| bsw@0 | 80         routes = main.get; | 
| bsw@0 | 81         break; | 
| bsw@0 | 82 | 
| bsw@0 | 83       case 'DELETE': | 
| bsw@0 | 84         // delete requests are handled like post request with parameter delete=1 | 
| bsw@0 | 85         params.delete = '1'; | 
| bsw@0 | 86 | 
| bsw@0 | 87       case 'POST': | 
| bsw@0 | 88         routes = main.post; | 
| bsw@0 | 89         break; | 
| bsw@0 | 90 | 
| bsw@0 | 91       default: | 
| bsw@0 | 92         main.respond('json', null, req, res, 'not found'); | 
| bsw@0 | 93         break; | 
| bsw@0 | 94 | 
| bsw@0 | 95     }; | 
| bsw@0 | 96 | 
| bsw@0 | 97     // dispatch request based on method and url | 
| bsw@0 | 98 | 
| bsw@0 | 99     var routing_target = routes[url_info.pathname] | 
| bsw@0 | 100     if (routing_target) { | 
| bsw@0 | 101       db.query(config.connectionString, req, res, 'START TRANSACTION ISOLATION LEVEL READ COMMITTED READ WRITE', function (result, conn) { | 
| bsw@0 | 102         routing_target.apply(this, [conn, req, res, params]); | 
| bsw@0 | 103       }); | 
| bsw@0 | 104     } else { | 
| bsw@0 | 105       main.respond('json', null, req, res, 'not found'); | 
| bsw@0 | 106     }; | 
| bsw@0 | 107 | 
| bsw@0 | 108   }); | 
| bsw@0 | 109 | 
| bsw@0 | 110 // actually connect the http server to a network interface | 
| bsw@0 | 111 }).listen(config.bind_port, config.bind_address); | 
| bsw@0 | 112 | 
| bsw@0 | 113 console.log('LiquidFeedback API server started with ' + config.public_access_level + ' public access at ' + config.bind_address + ':' + config.bind_port); | 
| bsw@0 | 114 | 
| bsw@0 | 115 | 
| bsw@0 | 116 |