pixl-server-web 1.3.21 → 1.3.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -2
- package/lib/http.js +20 -15
- package/lib/https.js +21 -16
- package/lib/response.js +2 -0
- package/package.json +1 -1
- package/test/test.js +58 -0
- package/web_server.js +45 -19
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
8
8
|
- [Usage](#usage)
|
|
9
9
|
- [Configuration](#configuration)
|
|
10
10
|
* [http_port](#http_port)
|
|
11
|
+
* [http_alt_ports](#http_alt_ports)
|
|
11
12
|
* [http_bind_address](#http_bind_address)
|
|
12
13
|
* [http_htdocs_dir](#http_htdocs_dir)
|
|
13
14
|
* [http_max_upload_size](#http_max_upload_size)
|
|
@@ -47,12 +48,14 @@ This module is a component for use in [pixl-server](https://www.github.com/jhuck
|
|
|
47
48
|
* [http_clean_headers](#http_clean_headers)
|
|
48
49
|
* [http_log_socket_errors](#http_log_socket_errors)
|
|
49
50
|
* [http_full_uri_match](#http_full_uri_match)
|
|
51
|
+
* [http_flatten_query](#http_flatten_query)
|
|
50
52
|
* [http_req_max_dump_enabled](#http_req_max_dump_enabled)
|
|
51
53
|
* [http_req_max_dump_dir](#http_req_max_dump_dir)
|
|
52
54
|
* [http_req_max_dump_debounce](#http_req_max_dump_debounce)
|
|
53
55
|
* [http_public_ip_offset](#http_public_ip_offset)
|
|
54
56
|
* [https](#https)
|
|
55
57
|
* [https_port](#https_port)
|
|
58
|
+
* [https_alt_ports](#https_alt_ports)
|
|
56
59
|
* [https_cert_file](#https_cert_file)
|
|
57
60
|
* [https_key_file](#https_key_file)
|
|
58
61
|
* [https_ca_file](#https_ca_file)
|
|
@@ -167,11 +170,22 @@ The configuration for this component is set by passing in a `WebServer` key in t
|
|
|
167
170
|
|
|
168
171
|
## http_port
|
|
169
172
|
|
|
170
|
-
This is the port to listen on. The standard web port is 80, but note that only the root user can listen on ports below 1024.
|
|
173
|
+
This is the main port to listen on. The standard web port is 80, but note that only the root user can listen on ports below 1024.
|
|
174
|
+
|
|
175
|
+
## http_alt_ports
|
|
176
|
+
|
|
177
|
+
If you would like to have the server listen on additional ports, add them here as an array. Example:
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
{
|
|
181
|
+
"http_port": 80,
|
|
182
|
+
"http_alt_ports": [ 3000, 8080 ]
|
|
183
|
+
}
|
|
184
|
+
```
|
|
171
185
|
|
|
172
186
|
## http_bind_address
|
|
173
187
|
|
|
174
|
-
Optionally specify an exact local IP address to bind the
|
|
188
|
+
Optionally specify an exact local IP address to bind the listeners to. By default this binds to all available addresses on the machine. Example:
|
|
175
189
|
|
|
176
190
|
```js
|
|
177
191
|
{
|
|
@@ -571,6 +585,17 @@ This boolean allows you to enable HTTPS (SSL) support in the web server. It def
|
|
|
571
585
|
|
|
572
586
|
If HTTPS mode is enabled, this is the port to listen on for secure requests. The standard HTTPS port is 443.
|
|
573
587
|
|
|
588
|
+
## https_alt_ports
|
|
589
|
+
|
|
590
|
+
If you would like to have the server listen on additional HTTPS ports, add them here as an array. Example:
|
|
591
|
+
|
|
592
|
+
```js
|
|
593
|
+
{
|
|
594
|
+
"https_port": 443,
|
|
595
|
+
"https_alt_ports": [ 9000, 9001 ]
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
574
599
|
## https_cert_file
|
|
575
600
|
|
|
576
601
|
If HTTPS mode is enabled, this should point to your SSL certificate file on disk. The certificate file typically has a `.crt` filename extension, or possibly `cert.pem` if using [Let's Encrypt](https://letsencrypt.org/).
|
package/lib/http.js
CHANGED
|
@@ -8,10 +8,9 @@ const Perf = require('pixl-perf');
|
|
|
8
8
|
|
|
9
9
|
module.exports = class HTTP {
|
|
10
10
|
|
|
11
|
-
startHTTP(callback) {
|
|
11
|
+
startHTTP(port, callback) {
|
|
12
12
|
// start http server
|
|
13
13
|
var self = this;
|
|
14
|
-
var port = this.config.get('http_port');
|
|
15
14
|
var bind_addr = this.config.get('http_bind_address') || '';
|
|
16
15
|
var max_conns = this.config.get('http_max_connections') || 0;
|
|
17
16
|
var https_force = self.config.get('https_force') || false;
|
|
@@ -52,14 +51,14 @@ module.exports = class HTTP {
|
|
|
52
51
|
}
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
var listener = require('http').createServer( handler );
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
listener.on('connection', function(socket) {
|
|
58
57
|
var ip = socket.remoteAddress || '';
|
|
59
58
|
|
|
60
59
|
if (max_conns && (self.numConns >= max_conns)) {
|
|
61
60
|
// reached maximum concurrent connections, abort new ones
|
|
62
|
-
self.logError('maxconns', "Maximum concurrent connections reached, denying connection from: " + ip, { ip: ip, max: max_conns });
|
|
61
|
+
self.logError('maxconns', "Maximum concurrent connections reached, denying connection from: " + ip, { ip: ip, port: port, max: max_conns });
|
|
63
62
|
socket.end();
|
|
64
63
|
socket.unref();
|
|
65
64
|
socket.destroy(); // hard close
|
|
@@ -68,7 +67,7 @@ module.exports = class HTTP {
|
|
|
68
67
|
}
|
|
69
68
|
if (self.server.shut) {
|
|
70
69
|
// server is shutting down, abort new connections
|
|
71
|
-
self.logError('shutdown', "Server is shutting down, denying connection from: " + ip, { ip: ip });
|
|
70
|
+
self.logError('shutdown', "Server is shutting down, denying connection from: " + ip, { ip: ip, port: port });
|
|
72
71
|
socket.end();
|
|
73
72
|
socket.unref();
|
|
74
73
|
socket.destroy(); // hard close
|
|
@@ -78,7 +77,7 @@ module.exports = class HTTP {
|
|
|
78
77
|
var id = self.getNextId('c');
|
|
79
78
|
self.conns[ id ] = socket;
|
|
80
79
|
self.numConns++;
|
|
81
|
-
self.logDebug(8, "New incoming HTTP connection: " + id, { ip: ip, num_conns: self.numConns });
|
|
80
|
+
self.logDebug(8, "New incoming HTTP connection: " + id, { ip: ip, port: port, num_conns: self.numConns });
|
|
82
81
|
|
|
83
82
|
// Disable the Nagle algorithm.
|
|
84
83
|
socket.setNoDelay( true );
|
|
@@ -86,6 +85,7 @@ module.exports = class HTTP {
|
|
|
86
85
|
// add our own metadata to socket
|
|
87
86
|
socket._pixl_data = {
|
|
88
87
|
id: id,
|
|
88
|
+
port: port,
|
|
89
89
|
proto: 'http',
|
|
90
90
|
port: port,
|
|
91
91
|
time_start: (new Date()).getTime(),
|
|
@@ -101,6 +101,7 @@ module.exports = class HTTP {
|
|
|
101
101
|
var msg = "Socket preliminary timeout waiting for initial request (" + socket_prelim_timeout + " seconds)";
|
|
102
102
|
var err_args = {
|
|
103
103
|
ip: ip,
|
|
104
|
+
port: port,
|
|
104
105
|
pending: self.queue.length(),
|
|
105
106
|
active: self.queue.running(),
|
|
106
107
|
sockets: self.numConns
|
|
@@ -132,6 +133,7 @@ module.exports = class HTTP {
|
|
|
132
133
|
self.logError(err.code || 'socket', "Socket error: " + id + ": " + msg, {
|
|
133
134
|
ip: ip,
|
|
134
135
|
ips: args.ips,
|
|
136
|
+
port: port,
|
|
135
137
|
state: args.state,
|
|
136
138
|
method: args.request.method,
|
|
137
139
|
uri: args.request.url,
|
|
@@ -156,6 +158,7 @@ module.exports = class HTTP {
|
|
|
156
158
|
var now = (new Date()).getTime();
|
|
157
159
|
self.logDebug(8, "HTTP connection has closed: " + id, {
|
|
158
160
|
ip: ip,
|
|
161
|
+
port: port,
|
|
159
162
|
total_elapsed: now - socket._pixl_data.time_start,
|
|
160
163
|
num_requests: socket._pixl_data.num_requests,
|
|
161
164
|
bytes_in: socket._pixl_data.bytes_in,
|
|
@@ -167,7 +170,7 @@ module.exports = class HTTP {
|
|
|
167
170
|
} );
|
|
168
171
|
} );
|
|
169
172
|
|
|
170
|
-
|
|
173
|
+
listener.on('clientError', function(err, socket) {
|
|
171
174
|
// https://nodejs.org/api/http.html#http_event_clienterror
|
|
172
175
|
if (!socket._pixl_data) socket._pixl_data = {};
|
|
173
176
|
var args = socket._pixl_data.current || { request: {}, id: 'n/a' };
|
|
@@ -181,6 +184,7 @@ module.exports = class HTTP {
|
|
|
181
184
|
id: args.id,
|
|
182
185
|
ip: socket.remoteAddress,
|
|
183
186
|
ips: args.ips,
|
|
187
|
+
port: port,
|
|
184
188
|
state: args.state,
|
|
185
189
|
method: args.request.method,
|
|
186
190
|
uri: args.request.url,
|
|
@@ -208,36 +212,37 @@ module.exports = class HTTP {
|
|
|
208
212
|
}
|
|
209
213
|
});
|
|
210
214
|
|
|
211
|
-
|
|
215
|
+
listener.once('error', function(err) {
|
|
212
216
|
// fatal startup error on HTTP server, probably EADDRINUSE
|
|
213
|
-
self.logError('startup', "Failed to start HTTP listener: " + err.message);
|
|
217
|
+
self.logError('startup', "Failed to start HTTP listener on port: " + port + ": " + err.message);
|
|
214
218
|
return callback(err);
|
|
215
219
|
} );
|
|
216
220
|
|
|
217
221
|
var listen_opts = { port: port };
|
|
218
222
|
if (bind_addr) listen_opts.host = bind_addr;
|
|
219
223
|
|
|
220
|
-
|
|
224
|
+
listener.listen( listen_opts, function(err) {
|
|
221
225
|
if (err) {
|
|
222
|
-
self.logError('startup', "Failed to start HTTP listener: " + err.message);
|
|
226
|
+
self.logError('startup', "Failed to start HTTP listener on port: " + port + ": " + err.message);
|
|
223
227
|
return callback(err);
|
|
224
228
|
}
|
|
225
|
-
var info =
|
|
229
|
+
var info = listener.address();
|
|
226
230
|
self.logDebug(3, "Now listening for HTTP connections", info);
|
|
227
231
|
if (!port) {
|
|
228
232
|
port = info.port;
|
|
229
233
|
self.config.set('http_port', port);
|
|
230
234
|
self.logDebug(3, "Actual HTTP listener port chosen: " + port);
|
|
231
235
|
}
|
|
236
|
+
self.listeners.push(listener);
|
|
232
237
|
callback();
|
|
233
238
|
} );
|
|
234
239
|
|
|
235
240
|
// set idle socket timeout
|
|
236
241
|
if (this.config.get('http_timeout')) {
|
|
237
|
-
|
|
242
|
+
listener.setTimeout( this.config.get('http_timeout') * 1000 );
|
|
238
243
|
}
|
|
239
244
|
if (this.config.get('http_keep_alive_timeout')) {
|
|
240
|
-
|
|
245
|
+
listener.keepAliveTimeout = this.config.get('http_keep_alive_timeout') * 1000;
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
248
|
|
package/lib/https.js
CHANGED
|
@@ -18,10 +18,9 @@ const ACL = require('pixl-acl');
|
|
|
18
18
|
|
|
19
19
|
module.exports = class HTTP2 {
|
|
20
20
|
|
|
21
|
-
startHTTPS(callback) {
|
|
21
|
+
startHTTPS(port, callback) {
|
|
22
22
|
// start https server
|
|
23
23
|
var self = this;
|
|
24
|
-
var port = this.config.get('https_port');
|
|
25
24
|
var bind_addr = this.config.get('https_bind_address') || this.config.get('http_bind_address') || '';
|
|
26
25
|
var max_conns = this.config.get('https_max_connections') || this.config.get('http_max_connections') || 0;
|
|
27
26
|
var socket_prelim_timeout = self.config.get('https_socket_prelim_timeout') || self.config.get('http_socket_prelim_timeout') || 0;
|
|
@@ -50,14 +49,14 @@ module.exports = class HTTP2 {
|
|
|
50
49
|
// optional chain.pem or the like
|
|
51
50
|
opts.ca = fs.readFileSync( this.config.get('https_ca_file') );
|
|
52
51
|
}
|
|
53
|
-
|
|
52
|
+
var listener = require('https').createServer( opts, handler );
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
listener.on('secureConnection', function(socket) {
|
|
56
55
|
var ip = socket.remoteAddress || '';
|
|
57
56
|
|
|
58
57
|
if (max_conns && (self.numConns >= max_conns)) {
|
|
59
58
|
// reached maximum concurrent connections, abort new ones
|
|
60
|
-
self.logError('maxconns', "Maximum concurrent connections reached, denying request from: " + ip, { ip: ip, max: max_conns });
|
|
59
|
+
self.logError('maxconns', "Maximum concurrent connections reached, denying request from: " + ip, { ip: ip, port: port, max: max_conns });
|
|
61
60
|
socket.end();
|
|
62
61
|
socket.unref();
|
|
63
62
|
socket.destroy(); // hard close
|
|
@@ -66,7 +65,7 @@ module.exports = class HTTP2 {
|
|
|
66
65
|
}
|
|
67
66
|
if (self.server.shut) {
|
|
68
67
|
// server is shutting down, abort new connections
|
|
69
|
-
self.logError('shutdown', "Server is shutting down, denying connection from: " + ip, { ip: ip });
|
|
68
|
+
self.logError('shutdown', "Server is shutting down, denying connection from: " + ip, { ip: ip, port: port});
|
|
70
69
|
socket.end();
|
|
71
70
|
socket.unref();
|
|
72
71
|
socket.destroy(); // hard close
|
|
@@ -76,7 +75,7 @@ module.exports = class HTTP2 {
|
|
|
76
75
|
var id = self.getNextId('cs');
|
|
77
76
|
self.conns[ id ] = socket;
|
|
78
77
|
self.numConns++;
|
|
79
|
-
self.logDebug(8, "New incoming HTTPS (SSL) connection: " + id, { ip: ip, num_conns: self.numConns });
|
|
78
|
+
self.logDebug(8, "New incoming HTTPS (SSL) connection: " + id, { ip: ip, port: port, num_conns: self.numConns });
|
|
80
79
|
|
|
81
80
|
// Disable the Nagle algorithm.
|
|
82
81
|
socket.setNoDelay( true );
|
|
@@ -84,6 +83,7 @@ module.exports = class HTTP2 {
|
|
|
84
83
|
// add our own metadata to socket
|
|
85
84
|
socket._pixl_data = {
|
|
86
85
|
id: id,
|
|
86
|
+
port: port,
|
|
87
87
|
proto: 'https',
|
|
88
88
|
port: port,
|
|
89
89
|
time_start: (new Date()).getTime(),
|
|
@@ -99,6 +99,7 @@ module.exports = class HTTP2 {
|
|
|
99
99
|
var msg = "Socket preliminary timeout waiting for initial request (" + socket_prelim_timeout + " seconds)";
|
|
100
100
|
var err_args = {
|
|
101
101
|
ip: ip,
|
|
102
|
+
port: port,
|
|
102
103
|
pending: self.queue.length(),
|
|
103
104
|
active: self.queue.running(),
|
|
104
105
|
sockets: self.numConns
|
|
@@ -130,6 +131,7 @@ module.exports = class HTTP2 {
|
|
|
130
131
|
self.logError(err.code || 'socket', "Socket error: " + id + ": " + msg, {
|
|
131
132
|
ip: ip,
|
|
132
133
|
ips: args.ips,
|
|
134
|
+
port: port,
|
|
133
135
|
state: args.state,
|
|
134
136
|
method: args.request.method,
|
|
135
137
|
uri: args.request.url,
|
|
@@ -154,6 +156,7 @@ module.exports = class HTTP2 {
|
|
|
154
156
|
var now = (new Date()).getTime();
|
|
155
157
|
self.logDebug(8, "HTTPS (SSL) connection has closed: " + id, {
|
|
156
158
|
ip: ip,
|
|
159
|
+
port: port,
|
|
157
160
|
total_elapsed: now - socket._pixl_data.time_start,
|
|
158
161
|
num_requests: socket._pixl_data.num_requests,
|
|
159
162
|
bytes_in: socket._pixl_data.bytes_in,
|
|
@@ -165,7 +168,7 @@ module.exports = class HTTP2 {
|
|
|
165
168
|
} );
|
|
166
169
|
} );
|
|
167
170
|
|
|
168
|
-
|
|
171
|
+
listener.on('clientError', function(err, socket) {
|
|
169
172
|
// https://nodejs.org/api/http.html#http_event_clienterror
|
|
170
173
|
if (!socket._pixl_data) socket._pixl_data = {};
|
|
171
174
|
var args = socket._pixl_data.current || { request: {}, id: 'n/a' };
|
|
@@ -179,6 +182,7 @@ module.exports = class HTTP2 {
|
|
|
179
182
|
id: args.id,
|
|
180
183
|
ip: socket.remoteAddress,
|
|
181
184
|
ips: args.ips,
|
|
185
|
+
port: port,
|
|
182
186
|
state: args.state,
|
|
183
187
|
method: args.request.method,
|
|
184
188
|
uri: args.request.url,
|
|
@@ -206,40 +210,41 @@ module.exports = class HTTP2 {
|
|
|
206
210
|
}
|
|
207
211
|
});
|
|
208
212
|
|
|
209
|
-
|
|
213
|
+
listener.once('error', function(err) {
|
|
210
214
|
// fatal startup error on HTTPS server, probably EADDRINUSE
|
|
211
|
-
self.logError('startup', "Failed to start HTTPS listener: " + err.message);
|
|
215
|
+
self.logError('startup', "Failed to start HTTPS listener on port: " + port + ": " + err.message);
|
|
212
216
|
return callback(err);
|
|
213
217
|
} );
|
|
214
218
|
|
|
215
219
|
var listen_opts = { port: port };
|
|
216
220
|
if (bind_addr) listen_opts.host = bind_addr;
|
|
217
221
|
|
|
218
|
-
|
|
222
|
+
listener.listen( listen_opts, function(err) {
|
|
219
223
|
if (err) {
|
|
220
|
-
self.logError('startup', "Failed to start HTTPS listener: " + err.message);
|
|
224
|
+
self.logError('startup', "Failed to start HTTPS listener on port: " + port + ": " + err.message);
|
|
221
225
|
return callback(err);
|
|
222
226
|
}
|
|
223
|
-
var info =
|
|
227
|
+
var info = listener.address();
|
|
224
228
|
self.logDebug(3, "Now listening for HTTPS connections", info);
|
|
225
229
|
if (!port) {
|
|
226
230
|
port = info.port;
|
|
227
231
|
self.config.set('https_port', port);
|
|
228
232
|
self.logDebug(3, "Actual HTTPS listener port chosen: " + port);
|
|
229
233
|
}
|
|
234
|
+
self.listeners.push(listener);
|
|
230
235
|
callback();
|
|
231
236
|
} );
|
|
232
237
|
|
|
233
238
|
// set idle socket timeout
|
|
234
239
|
var timeout_sec = this.config.get('https_timeout') || this.config.get('http_timeout') || 0;
|
|
235
240
|
if (timeout_sec) {
|
|
236
|
-
|
|
241
|
+
listener.setTimeout( timeout_sec * 1000 );
|
|
237
242
|
}
|
|
238
243
|
if (this.config.get('https_keep_alive_timeout')) {
|
|
239
|
-
|
|
244
|
+
listener.keepAliveTimeout = this.config.get('https_keep_alive_timeout') * 1000;
|
|
240
245
|
}
|
|
241
246
|
else if (this.config.get('http_keep_alive_timeout')) {
|
|
242
|
-
|
|
247
|
+
listener.keepAliveTimeout = this.config.get('http_keep_alive_timeout') * 1000;
|
|
243
248
|
}
|
|
244
249
|
}
|
|
245
250
|
|
package/lib/response.js
CHANGED
|
@@ -326,6 +326,8 @@ module.exports = class Response {
|
|
|
326
326
|
id: args.id,
|
|
327
327
|
proto: args.request.headers['ssl'] ? 'https' : socket_data.proto,
|
|
328
328
|
ips: args.ips,
|
|
329
|
+
port: socket_data.port,
|
|
330
|
+
socket: socket_data.id,
|
|
329
331
|
host: args.request.headers['host'] || '',
|
|
330
332
|
ua: args.request.headers['user-agent'] || '',
|
|
331
333
|
perf: metrics
|
package/package.json
CHANGED
package/test/test.js
CHANGED
|
@@ -33,6 +33,7 @@ var server = new PixlServer({
|
|
|
33
33
|
|
|
34
34
|
"WebServer": {
|
|
35
35
|
"http_port": 3020,
|
|
36
|
+
"http_alt_ports": [3120],
|
|
36
37
|
"http_htdocs_dir": __dirname,
|
|
37
38
|
"http_max_upload_size": 1024 * 10,
|
|
38
39
|
"http_static_ttl": 3600,
|
|
@@ -53,6 +54,7 @@ var server = new PixlServer({
|
|
|
53
54
|
|
|
54
55
|
"https": 1,
|
|
55
56
|
"https_port": 3021,
|
|
57
|
+
"https_alt_ports": [3121],
|
|
56
58
|
"https_cert_file": "ssl.crt",
|
|
57
59
|
"https_key_file": "ssl.key",
|
|
58
60
|
"https_force": 0,
|
|
@@ -191,6 +193,33 @@ module.exports = {
|
|
|
191
193
|
);
|
|
192
194
|
},
|
|
193
195
|
|
|
196
|
+
function testHTTPAltPort(test) {
|
|
197
|
+
// test simple HTTP GET request to webserver backend, alternate port
|
|
198
|
+
request.json( 'http://127.0.0.1:3120/json', false,
|
|
199
|
+
{
|
|
200
|
+
headers: {
|
|
201
|
+
'X-Test': "Test"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
function(err, resp, json, perf) {
|
|
205
|
+
test.ok( !err, "No error from PixlRequest: " + err );
|
|
206
|
+
test.ok( !!resp, "Got resp from PixlRequest" );
|
|
207
|
+
test.ok( resp.statusCode == 200, "Got 200 response: " + resp.statusCode );
|
|
208
|
+
test.ok( resp.headers['via'] == "WebServerTest 1.0", "Correct Via header: " + resp.headers['via'] );
|
|
209
|
+
test.ok( !!json, "Got JSON in response" );
|
|
210
|
+
test.ok( json.code == 0, "Correct code in JSON response: " + json.code );
|
|
211
|
+
test.ok( !!json.user, "Found user object in JSON response" );
|
|
212
|
+
test.ok( json.user.Name == "Joe", "Correct user name in JSON response: " + json.user.Name );
|
|
213
|
+
|
|
214
|
+
// request headers will be echoed back
|
|
215
|
+
test.ok( !!json.headers, "Found headers echoed in JSON response" );
|
|
216
|
+
test.ok( json.headers['x-test'] == "Test", "Found Test header echoed in JSON response" );
|
|
217
|
+
|
|
218
|
+
test.done();
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
},
|
|
222
|
+
|
|
194
223
|
function testBadRequest(test) {
|
|
195
224
|
// test bad HTTP GET request to webserver backend
|
|
196
225
|
// this still resolves to the root dir index due to the ../
|
|
@@ -1576,6 +1605,35 @@ module.exports = {
|
|
|
1576
1605
|
);
|
|
1577
1606
|
},
|
|
1578
1607
|
|
|
1608
|
+
function testHTTPSAltPort(test) {
|
|
1609
|
+
// test HTTPS GET request to webserver backend on alt port
|
|
1610
|
+
request.json( 'https://127.0.0.1:3121/json', false,
|
|
1611
|
+
{
|
|
1612
|
+
rejectUnauthorized: false, // self-signed cert
|
|
1613
|
+
headers: {
|
|
1614
|
+
'X-Test': "Test"
|
|
1615
|
+
}
|
|
1616
|
+
},
|
|
1617
|
+
function(err, resp, json, perf) {
|
|
1618
|
+
test.ok( !err, "No error from PixlRequest: " + err );
|
|
1619
|
+
test.ok( !!resp, "Got resp from PixlRequest" );
|
|
1620
|
+
test.ok( resp.statusCode == 200, "Got 200 response: " + resp.statusCode );
|
|
1621
|
+
test.ok( resp.headers['via'] == "WebServerTest 1.0", "Correct Via header: " + resp.headers['via'] );
|
|
1622
|
+
test.ok( !!json, "Got JSON in response" );
|
|
1623
|
+
test.ok( json.code == 0, "Correct code in JSON response: " + json.code );
|
|
1624
|
+
test.ok( !!json.user, "Found user object in JSON response" );
|
|
1625
|
+
test.ok( json.user.Name == "Joe", "Correct user name in JSON response: " + json.user.Name );
|
|
1626
|
+
|
|
1627
|
+
// request headers will be echoed back
|
|
1628
|
+
test.ok( !!json.headers, "Found headers echoed in JSON response" );
|
|
1629
|
+
test.ok( json.headers['x-test'] == "Test", "Found Test header echoed in JSON response" );
|
|
1630
|
+
test.ok( !!json.headers.ssl, "SSL pseudo-header present in echo" );
|
|
1631
|
+
|
|
1632
|
+
test.done();
|
|
1633
|
+
}
|
|
1634
|
+
);
|
|
1635
|
+
},
|
|
1636
|
+
|
|
1579
1637
|
function testHTTPSPost(test) {
|
|
1580
1638
|
request.post( 'https://127.0.0.1:3021/json',
|
|
1581
1639
|
{
|
package/web_server.js
CHANGED
|
@@ -91,6 +91,7 @@ class WebServer extends Component {
|
|
|
91
91
|
this.logDebug(2, "pixl-server-web v" + this.version + " starting up");
|
|
92
92
|
|
|
93
93
|
// setup connections and handlers
|
|
94
|
+
this.listeners = [];
|
|
94
95
|
this.conns = {};
|
|
95
96
|
this.requests = {};
|
|
96
97
|
this.uriFilters = [];
|
|
@@ -194,16 +195,41 @@ class WebServer extends Component {
|
|
|
194
195
|
// listen for tick events to swap stat buffers
|
|
195
196
|
this.server.on( 'tick', this.tick.bind(this) );
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
this.startAll(callback);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
startAll(callback) {
|
|
202
|
+
// start all HTTP(s) listeners
|
|
203
|
+
var self = this;
|
|
204
|
+
var tasks = [];
|
|
205
|
+
|
|
206
|
+
// always start plain HTTP on base port
|
|
207
|
+
tasks.push([ this.config.get('http_port'), 'startHTTP' ]);
|
|
208
|
+
|
|
209
|
+
// optional additional ports
|
|
210
|
+
(this.config.get('http_alt_ports') || []).forEach( function(port) {
|
|
211
|
+
tasks.push([ port, 'startHTTP' ]);
|
|
206
212
|
} );
|
|
213
|
+
|
|
214
|
+
// optional HTTPS
|
|
215
|
+
if (this.config.get('https')) {
|
|
216
|
+
tasks.push([ this.config.get('https_port'), 'startHTTPS' ]);
|
|
217
|
+
|
|
218
|
+
// optional additional ports
|
|
219
|
+
(this.config.get('https_alt_ports') || []).forEach( function(port) {
|
|
220
|
+
tasks.push([ port, 'startHTTPS' ]);
|
|
221
|
+
} );
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// start all listeners in parallel
|
|
225
|
+
async.each( tasks,
|
|
226
|
+
function(task, callback) {
|
|
227
|
+
var port = task[0];
|
|
228
|
+
var func = task[1];
|
|
229
|
+
self[func](port, callback);
|
|
230
|
+
},
|
|
231
|
+
callback
|
|
232
|
+
);
|
|
207
233
|
}
|
|
208
234
|
|
|
209
235
|
dumpAllRequests(callback) {
|
|
@@ -263,12 +289,13 @@ class WebServer extends Component {
|
|
|
263
289
|
getStats() {
|
|
264
290
|
// get current stats, merged with live socket and request info
|
|
265
291
|
var socket_info = {};
|
|
266
|
-
var listener_info =
|
|
292
|
+
var listener_info = [];
|
|
267
293
|
var now = (new Date()).getTime();
|
|
268
294
|
var num_sockets = 0;
|
|
269
295
|
|
|
270
|
-
|
|
271
|
-
|
|
296
|
+
listener_info = this.listeners.map( function(listener) {
|
|
297
|
+
return listener.address();
|
|
298
|
+
} );
|
|
272
299
|
|
|
273
300
|
for (var key in this.conns) {
|
|
274
301
|
var socket = this.conns[key];
|
|
@@ -432,7 +459,7 @@ class WebServer extends Component {
|
|
|
432
459
|
// shutdown http server
|
|
433
460
|
var self = this;
|
|
434
461
|
|
|
435
|
-
if (this.
|
|
462
|
+
if (this.listeners.length) {
|
|
436
463
|
this.logDebug(2, "Shutting down HTTP server");
|
|
437
464
|
|
|
438
465
|
for (var id in this.requests) {
|
|
@@ -461,12 +488,11 @@ class WebServer extends Component {
|
|
|
461
488
|
this.numConns--;
|
|
462
489
|
} // foreach conn
|
|
463
490
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
// delete this.http;
|
|
491
|
+
// close all listeners
|
|
492
|
+
this.listeners.forEach( function(listener) {
|
|
493
|
+
var info = listener.address() || { port: 'n/a' };
|
|
494
|
+
listener.close( function() { self.logDebug(3, "HTTP server on port " + info.port + " has shut down.", info); } );
|
|
495
|
+
} );
|
|
470
496
|
|
|
471
497
|
this.requests = {};
|
|
472
498
|
this.queue.kill();
|