forked from jhurliman/node-echoprint-server
-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.js
138 lines (115 loc) · 3.81 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Simple HTTP server module
*/
var http = require('http');
var urlParser = require('url');
var qs = require('querystring');
var log = require('winston');
var jade = require('jade');
var config = require('./config');
var api = require('./controllers/api');
var debug = require('./controllers/debug');
exports.init = init;
exports.renderView = renderView;
exports.respond = respond;
var TIMEOUT = 1000 * 60;
/**
* Initialize the HTTP endpoints.
*/
function init() {
http.createServer(function(req, res) {
req.start = new Date();
req.timer = setTimeout(function() { timeout(req, res); }, TIMEOUT);
var url = urlParser.parse(req.url, true);
var path = url.pathname.split('/', 16);
if (req.method === 'GET') {
if (path[1] === 'query')
return api.query(req, res);
if (path[1] === 'deletefp')
return api.deletefp(req, res);
else if (path[1] === 'debug')
return debug.debugQuery(req, res);
} else if (req.method === 'POST') {
req.body = '';
req.on('data', function(data) { req.body += data; });
req.on('end', function() {
req.body = qs.parse(req.body);
if (path[1] === 'ingest')
return api.ingest(req, res);
else if (path[1] === 'debug')
return debug.debugQuery(req, res);
respond(req, res, 404, { error: 'Invalid API endpoint' });
});
return;
}
respond(req, res, 404, { error: 'Invalid API endpoint' });
}).addListener('clientError', function(ex) {
log.warn('Client error: ' + ex);
}).listen(config.web_port, config.listen_address);
log.info('HTTP listening on port ' + config.web_port);
}
/**
* Render a view template and send it as an HTTP response.
*/
function renderView(req, res, statusCode, view, options, headers) {
jade.renderFile(__dirname + '/views/' + view, options, function(err, html) {
if (err) {
log.error('Failed to render ' + view + ': ' + err);
return respond(req, res, 500, 'Internal server error', headers);
}
respond(req, res, 200, html, headers);
});
}
/**
* Send an HTTP response to a client.
*/
function respond(req, res, statusCode, body, headers) {
// Destroy the response timeout timer
clearTimeout(req.timer);
statusCode = statusCode || 200;
if (!headers)
headers = {};
if (typeof body !== 'string') {
body = JSON.stringify(body);
headers['Content-Type'] = 'application/json';
} else {
headers['Content-Type'] = 'text/html';
}
var contentLength = body ? Buffer.byteLength(body, 'utf8') : '-';
if (body)
headers['Content-Length'] = contentLength;
var remoteAddress =
(req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress)));
var referrer = req.headers.referer || req.headers.referrer || '';
if (referrer.length > 128)
referrer = referrer.substr(0, 128) + ' ...';
var url = req.url;
if (url.length > 128)
url = url.substr(0, 128) + ' ...';
log.info(
remoteAddress +
' - - [' + (new Date()).toUTCString() + ']' +
' "' + req.method + ' ' + url +
' HTTP/' + req.httpVersionMajor + '.' + req.httpVersionMinor + '" ' +
statusCode + ' ' + contentLength +
' "' + referrer +
'" "' + (req.headers['user-agent'] || '') + '"');
try {
res.writeHead(200, headers);
res.end(body);
} catch (ex) {
log.error('Error sending response to ' + remoteAddress + ': ' + ex);
}
}
/**
* Handles server timeouts by logging an error and responding with a 503.
*/
function timeout(req, res) {
var remoteAddress =
(req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress)));
log.error('Timed out while responding to a request from ' + remoteAddress);
try {
res.writeHead(503);
res.end();
} catch (ex) { }
}