roster-server 3.0.0 → 3.0.2
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/index.js +1 -1
- package/lib/isolated-site.js +4 -1
- package/lib/site-worker.js +2 -0
- package/package.json +53 -53
- package/test/isolation.test.js +23 -0
- package/vendor/greenlock/bin/certonly.js +0 -0
- package/vendor/greenlock/bin/greenlock.js +0 -0
- package/vendor/greenlock/logo/beaker-browser-301x112.png +0 -0
- package/vendor/greenlock/logo/greenlock-1063x250.png +0 -0
- package/vendor/greenlock/logo/ibm-301x112.png +0 -0
- package/vendor/greenlock/logo/telebit-301x112.png +0 -0
- package/vendor/greenlock-express/scripts/postinstall +0 -0
package/index.js
CHANGED
|
@@ -985,7 +985,7 @@ class Roster {
|
|
|
985
985
|
socket.setTimeout(0);
|
|
986
986
|
const site = servername && this._isolatedSiteFor(routes, servername);
|
|
987
987
|
if (site) {
|
|
988
|
-
site.handoff(port, head, socket);
|
|
988
|
+
site.handoff(port, head, socket, () => this._sockets.delete(socket));
|
|
989
989
|
return;
|
|
990
990
|
}
|
|
991
991
|
socket.unshift(head);
|
package/lib/isolated-site.js
CHANGED
|
@@ -108,8 +108,10 @@ class IsolatedSite {
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* Pass an accepted client socket, with the bytes already read from it, to the site process.
|
|
111
|
+
* `onHandedOff` runs once the site process owns the connection; the main process never
|
|
112
|
+
* sees a 'close' event for it.
|
|
111
113
|
*/
|
|
112
|
-
handoff(port, head, socket) {
|
|
114
|
+
handoff(port, head, socket, onHandedOff) {
|
|
113
115
|
const child = this.child;
|
|
114
116
|
if (!this.ready || this.pending >= this.isolation.backlog) {
|
|
115
117
|
socket.destroy();
|
|
@@ -119,6 +121,7 @@ class IsolatedSite {
|
|
|
119
121
|
child.send({ type: 'connection', port, head: head.toString('base64') }, socket, error => {
|
|
120
122
|
if (this.child === child) this.pending--;
|
|
121
123
|
if (error) socket.destroy();
|
|
124
|
+
else onHandedOff();
|
|
122
125
|
});
|
|
123
126
|
}
|
|
124
127
|
|
package/lib/site-worker.js
CHANGED
|
@@ -138,6 +138,8 @@ process.on('disconnect', shutdown);
|
|
|
138
138
|
process.on('message', (message, handle) => {
|
|
139
139
|
if (message.type === 'start') start(message);
|
|
140
140
|
else if (message.type === 'connection') {
|
|
141
|
+
// A connection can close while its socket is being transferred over IPC.
|
|
142
|
+
if (!handle) return;
|
|
141
143
|
if (roster) roster.accept(message.port, Buffer.from(message.head, 'base64'), handle);
|
|
142
144
|
else handle.destroy();
|
|
143
145
|
} else if (message.type === 'certificate') roster.settleCertificate(message);
|
package/package.json
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
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
|
-
}
|
|
2
|
+
"name": "roster-server",
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "👾 RosterServer - A domain host router to host multiple HTTPS.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/clasen/RosterServer.git"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"greenlock",
|
|
12
|
+
"https",
|
|
13
|
+
"domain",
|
|
14
|
+
"multi-domain",
|
|
15
|
+
"letsencrypt",
|
|
16
|
+
"hosting",
|
|
17
|
+
"ssl",
|
|
18
|
+
"host",
|
|
19
|
+
"vhost",
|
|
20
|
+
"virtual-host",
|
|
21
|
+
"socket.io",
|
|
22
|
+
"websocket",
|
|
23
|
+
"express",
|
|
24
|
+
"greenlock-express",
|
|
25
|
+
"shotx",
|
|
26
|
+
"bun",
|
|
27
|
+
"clasen"
|
|
28
|
+
],
|
|
29
|
+
"author": "Martin Clasen",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/clasen/RosterServer/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/clasen/RosterServer#readme",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@greenlock/manager": "^3.1.0",
|
|
37
|
+
"@root/acme": "^3.1.0",
|
|
38
|
+
"@root/csr": "^0.8.1",
|
|
39
|
+
"@root/encoding": "^1.0.1",
|
|
40
|
+
"@root/keypairs": "^0.10.0",
|
|
41
|
+
"@root/mkdirp": "^1.0.0",
|
|
42
|
+
"@root/request": "^1.6.1",
|
|
43
|
+
"acme-dns-01-cli": "^3.0.7",
|
|
44
|
+
"acme-http-01-standalone": "^3.0.5",
|
|
45
|
+
"cert-info": "^1.5.1",
|
|
46
|
+
"greenlock-store-fs": "^3.2.2",
|
|
47
|
+
"lemonlog": "^1.2.0",
|
|
48
|
+
"redirect-https": "^1.3.1",
|
|
49
|
+
"safe-replace": "^1.1.0"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"test": "node --test 'test/**/*.test.js'"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/test/isolation.test.js
CHANGED
|
@@ -131,6 +131,29 @@ it('routes each SNI host to its own process with the client address and headers
|
|
|
131
131
|
assert.equal(redirect.headers.location, 'https://a.example.com/path');
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
+
it('keeps serving in the same worker when a connection arrives without a socket', { timeout: 20000 }, async t => {
|
|
135
|
+
const { roster, port } = await startProduction(t, {
|
|
136
|
+
'disconnected.example.com': `${REPORT_SITE}
|
|
137
|
+
process.on('message', message => {
|
|
138
|
+
if (message.type === 'connection' && message.head === '') process.send({ type: 'observed' });
|
|
139
|
+
});`
|
|
140
|
+
}, { certificates: ['disconnected.example.com'] });
|
|
141
|
+
const first = JSON.parse((await get(port, 'disconnected.example.com')).body);
|
|
142
|
+
const child = roster._isolatedSites[0].child;
|
|
143
|
+
const observed = Promise.race([
|
|
144
|
+
once(child, 'message').then(([message]) => message.type),
|
|
145
|
+
once(child, 'exit').then(() => 'exited')
|
|
146
|
+
]);
|
|
147
|
+
await new Promise((resolve, reject) => {
|
|
148
|
+
child.send({ type: 'connection', port: 443, head: '' }, error => error ? reject(error) : resolve());
|
|
149
|
+
});
|
|
150
|
+
assert.equal(await observed, 'observed', 'worker exited on a connection without a socket');
|
|
151
|
+
const response = await get(port, 'disconnected.example.com');
|
|
152
|
+
assert.equal(response.status, 200);
|
|
153
|
+
assert.equal(JSON.parse(response.body).pid, first.pid);
|
|
154
|
+
assert.equal(child.exitCode, null);
|
|
155
|
+
});
|
|
156
|
+
|
|
134
157
|
it('keeps serving other sites while one blocks its event loop', { timeout: 20000 }, async t => {
|
|
135
158
|
const { port } = await startProduction(t, {
|
|
136
159
|
'busy.example.com': `module.exports = () => (req, res) => {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|