123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /**
- * TraCINg-Server - Gathering and visualizing cyber incidents on the world
- *
- * Copyright 2013 Matthias Gazzari, Annemarie Mattmann, André Wolski
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /*
- * This module defines a http server with a static webroot and a https server
- * cappable of receiving POST data. Additionally a socket.io listener provides
- * realtime connection between server and clients.
- */
- // load node modules
- var http = require("http");
- var https = require("https");
- var statics = require("node-static"); // requires 'npm install node-static'
- var db = require("./db/database.js");
- var utils = require("./utils.js");
- var Router = require('router');
- var url = require('url');
- function handleError(code, message, response){
- response.statusCode = code;
- response.setHeader('Content-Type', 'text/plain; charset=utf-8');
- response.end(message + "\n");
- }
- function start(postHandle, ioListener, config, options) {
- var fileServer, postReceiver, io, router, httpsRouter;
- router = Router();
- router.get('/api/get_attacks', function(req, res){
- var filter = {};
- if(req.query.hasOwnProperty("country")){
- filter["countries"] = [req.query.country];
- }
- if(req.query.hasOwnProperty("latitude") && req.query.hasOwnProperty("longitude")){
- filter["location"] = [parseFloat(req.query.longitude), parseFloat(req.query.latitude)];
- if(req.query.hasOwnProperty("distance")){
- filter["distance"] = parseInt(req.query.distance, 10);
- }
- }
- if(req.query.hasOwnProperty("start")){
- filter["start"] = req.query.start;
- }
- if(req.query.hasOwnProperty("end")){
- filter["end"] = req.query.end;
- }
- if(req.query.hasOwnProperty("page")){
- filter["page"] = req.query.page;
- }
- res.setHeader('Content-Type', 'application/json; charset=utf-8');
- db.requestAttacks(filter, function(err, data){
- if(err){
- res.statusCode = 404;
- res.end();
- } else {
- res.end(JSON.stringify(data));
- }
- }, {type: 'response', response: res});
- });
- // http request
- function onRequestHttp(request, response) {
- console.log("http request received.");
- request.query = url.parse(request.url, true).query;
- router(request, response, function(){
- // try to serve files if nothing was matched
- fileServer.serve(request, response);
- });
- }
- // https request (POST only, no routing)
- function onRequestHttps(request, response) {
- var postData = "";
- //console.log("https request received.");
- var request_ip = request.headers['x-forwarded-for'] ||
- request.connection.remoteAddress ||
- request.socket.remoteAddress ||
- request.connection.socket.remoteAddress;
- var authorized = request.client.authorized;
- var sensor = {};
- var clientCert = request.connection.getPeerCertificate();
- if(clientCert && clientCert.subject){
- sensor["name"] = clientCert.subject.CN;
- sensor["type"] = clientCert.subject.O;
- if(clientCert.subject.OU){
- sensor["type"] += " " + clientCert.subject.OU;
- }
- console.log("Sensor information retrieved from client certificate: ", sensor);
- }
- // receive POST data
- request.on("data", function(chunk) {
- postData += chunk;
- // prohibit too large POST data
- if(postData.length > 1e6) {
- response.writeHead(413, {"Content-Type": "text/plain"});
- response.write("Request Entity Too Large");
- response.end();
- request.connection.destroy();
- }
- });
- // process received Data
- request.on("end", function() {
- if(request.url === "/sync"){
- if (postData) {
- try {
- var data = JSON.parse(postData);
- db.getEntriesFromSyncInfo(data, function(error, data){
- response.setHeader('Content-Type', 'application/json; charset=utf-8');
- response.statusCode = 200;
- response.end(JSON.stringify(data));
- });
- } catch(e) {
- handleError(400, "Invalid json-data given", response);
- }
- } else {
- handleError(400, "No content given", response);
- }
- return;
- }
- postHandle(response, postData, authorized, sensor, io, request_ip);
- });
- }
- db.connect(function() {
- // http Server
- var server = http.createServer(onRequestHttp).listen(config.httpPort);
- // file Server serving files from a specific folder
- fileServer = new (statics.Server)(config.webroot, {cache: 10, gzip: true}); // TODO remove cache time - test purpose
- // https Server
- postReceiver = https.createServer(options, onRequestHttps).listen(config.httpsPort);
- // io sockets listener (listens on same port as the http server)
- io = ioListener.listen(server);
- console.log("Server has started.");
- });
- }
- exports.start = start;
|