/
core.js
108 lines (90 loc) · 2.81 KB
/
core.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
/*
* core.js: Core functionality for the Flatiron HTTP (with SPDY support) plugin.
*
* (C) 2011, Charlie Robbins & the Contributors
* MIT LICENSE
*
*/
var http = require('http'),
https = require('https'),
fs = require('fs'),
stream = require('stream'),
HttpStream = require('./http-stream'),
RoutingStream = require('./routing-stream');
var core = exports;
core.createServer = function (options) {
var isArray = Array.isArray(options.after),
credentials;
if (!options) {
throw new Error('options is required to create a server');
}
function requestHandler(req, res) {
var routingStream = new RoutingStream({
before: options.before,
buffer: options.buffer,
//
// Remark: without new after is a huge memory leak that
// pipes to every single open connection
//
after: isArray && options.after.map(function (After) {
return new After;
}),
request: req,
response: res,
limit: options.limit,
headers: options.headers
});
routingStream.on('error', function (err) {
var fn = options.onError || core.errorHandler;
fn(err, routingStream, routingStream.target, function () {
routingStream.target.emit('next');
});
});
req.pipe(routingStream);
}
//
// both https and spdy requires same params
//
if (options.https || options.spdy) {
if (options.https && options.spdy) {
throw new Error('You shouldn\'t be using https and spdy simultaneously.');
}
var serverOptions,
credentials,
key = !options.spdy
? 'https'
: 'spdy';
serverOptions = options[key];
if (!serverOptions.key || !serverOptions.cert) {
throw new Error('Both options.' + key + '.`key` and options.' + key + '.`cert` are required.');
}
credentials = {
key: fs.readFileSync(serverOptions.key),
cert: fs.readFileSync(serverOptions.cert)
};
if (serverOptions.ca) {
serverOptions.ca = !Array.isArray(serverOptions.ca)
? [serverOptions.ca]
: serverOptions.ca
credentials.ca = serverOptions.ca.map(function (ca) {
return fs.readFileSync(ca);
});
}
if (options.spdy) {
// spdy is optional so we require module here rather than on top
var spdy = require('spdy');
return spdy.createServer(credentials, requestHandler);
}
return https.createServer(credentials, requestHandler);
}
return http.createServer(requestHandler);
};
core.errorHandler = function error(err, req, res) {
if (err) {
(this.res || res).writeHead(err.status || 500, err.headers || { "Content-Type": "text/plain" });
(this.res || res).end(err.message + "\n");
return;
}
(this.res || res).writeHead(404, {"Content-Type": "text/plain"});
(this.res || res).end("Not Found\n");
};