server.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /**
  2. * TraCINg-Server - Gathering and visualizing cyber incidents on the world
  3. *
  4. * Copyright 2013 Matthias Gazzari, Annemarie Mattmann, André Wolski
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. /*
  19. * This module defines a http server with a static webroot and a https server
  20. * cappable of receiving POST data. Additionally a socket.io listener provides
  21. * realtime connection between server and clients.
  22. */
  23. // load node modules
  24. var http = require("http");
  25. var https = require("https");
  26. var statics = require("node-static"); // requires 'npm install node-static'
  27. var db = require("./db/database.js");
  28. var utils = require("./utils.js");
  29. var Router = require('router');
  30. var url = require('url');
  31. function handleError(code, message, response){
  32. response.statusCode = code;
  33. response.setHeader('Content-Type', 'text/plain; charset=utf-8');
  34. response.end(message + "\n");
  35. }
  36. function start(postHandle, ioListener, config, options) {
  37. var fileServer, postReceiver, io, router, httpsRouter;
  38. router = Router();
  39. router.get('/api/get_attacks', function(req, res){
  40. var filter = {};
  41. if(req.query.hasOwnProperty("country")){
  42. filter["countries"] = [req.query.country];
  43. }
  44. if(req.query.hasOwnProperty("latitude") && req.query.hasOwnProperty("longitude")){
  45. filter["location"] = [parseFloat(req.query.longitude), parseFloat(req.query.latitude)];
  46. if(req.query.hasOwnProperty("distance")){
  47. filter["distance"] = parseInt(req.query.distance, 10);
  48. }
  49. }
  50. if(req.query.hasOwnProperty("start")){
  51. filter["start"] = req.query.start;
  52. }
  53. if(req.query.hasOwnProperty("end")){
  54. filter["end"] = req.query.end;
  55. }
  56. if(req.query.hasOwnProperty("page")){
  57. filter["page"] = req.query.page;
  58. }
  59. res.setHeader('Content-Type', 'application/json; charset=utf-8');
  60. db.requestAttacks(filter, function(err, data){
  61. if(err){
  62. res.statusCode = 404;
  63. res.end();
  64. } else {
  65. res.end(JSON.stringify(data));
  66. }
  67. }, {type: 'response', response: res});
  68. });
  69. // http request
  70. function onRequestHttp(request, response) {
  71. console.log("http request received.");
  72. request.query = url.parse(request.url, true).query;
  73. router(request, response, function(){
  74. // try to serve files if nothing was matched
  75. fileServer.serve(request, response);
  76. });
  77. }
  78. // https request (POST only, no routing)
  79. function onRequestHttps(request, response) {
  80. var postData = "";
  81. //console.log("https request received.");
  82. var request_ip = request.headers['x-forwarded-for'] ||
  83. request.connection.remoteAddress ||
  84. request.socket.remoteAddress ||
  85. request.connection.socket.remoteAddress;
  86. var authorized = request.client.authorized;
  87. var sensor = {};
  88. var clientCert = request.connection.getPeerCertificate();
  89. if(clientCert && clientCert.subject){
  90. sensor["name"] = clientCert.subject.CN;
  91. sensor["type"] = clientCert.subject.O;
  92. if(clientCert.subject.OU){
  93. sensor["type"] += " " + clientCert.subject.OU;
  94. }
  95. console.log("Sensor information retrieved from client certificate: ", sensor);
  96. }
  97. // receive POST data
  98. request.on("data", function(chunk) {
  99. postData += chunk;
  100. // prohibit too large POST data
  101. if(postData.length > 1e6) {
  102. response.writeHead(413, {"Content-Type": "text/plain"});
  103. response.write("Request Entity Too Large");
  104. response.end();
  105. request.connection.destroy();
  106. }
  107. });
  108. // process received Data
  109. request.on("end", function() {
  110. if(request.url === "/sync"){
  111. if (postData) {
  112. try {
  113. var data = JSON.parse(postData);
  114. db.getEntriesFromSyncInfo(data, function(error, data){
  115. response.setHeader('Content-Type', 'application/json; charset=utf-8');
  116. response.statusCode = 200;
  117. response.end(JSON.stringify(data));
  118. });
  119. } catch(e) {
  120. handleError(400, "Invalid json-data given", response);
  121. }
  122. } else {
  123. handleError(400, "No content given", response);
  124. }
  125. return;
  126. }
  127. postHandle(response, postData, authorized, sensor, io, request_ip);
  128. });
  129. }
  130. db.connect(function() {
  131. // http Server
  132. var server = http.createServer(onRequestHttp).listen(config.httpPort);
  133. // file Server serving files from a specific folder
  134. fileServer = new (statics.Server)(config.webroot, {cache: 10, gzip: true}); // TODO remove cache time - test purpose
  135. // https Server
  136. postReceiver = https.createServer(options, onRequestHttps).listen(config.httpsPort);
  137. // io sockets listener (listens on same port as the http server)
  138. io = ioListener.listen(server);
  139. console.log("Server has started.");
  140. });
  141. }
  142. exports.start = start;