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