git-watchtower 2.1.11 → 2.1.13
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/package.json +1 -1
- package/src/server/coordinator.js +19 -0
- package/src/server/web.js +8 -1
package/package.json
CHANGED
|
@@ -34,6 +34,18 @@ const WATCHTOWER_DIR = path.join(os.homedir(), '.watchtower');
|
|
|
34
34
|
*/
|
|
35
35
|
const MAX_IPC_BUFFER = 1024 * 1024;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Maximum number of concurrent worker connections the coordinator will
|
|
39
|
+
* accept. The legitimate ceiling is "one git-watchtower instance per
|
|
40
|
+
* project the user is actively working on" — a generous double-digit
|
|
41
|
+
* limit covers any real workflow. The cap exists so a buggy or
|
|
42
|
+
* malicious local process running as the same user can't open thousands
|
|
43
|
+
* of sockets and exhaust the coordinator's file descriptors. Beyond
|
|
44
|
+
* this limit, Node's net.Server closes incoming connections after
|
|
45
|
+
* accept() rather than handing them to the request listener.
|
|
46
|
+
*/
|
|
47
|
+
const MAX_WORKER_CONNECTIONS = 64;
|
|
48
|
+
|
|
37
49
|
/**
|
|
38
50
|
* How long a worker waits for a `registered` ACK from the coordinator
|
|
39
51
|
* after the TCP connection completes and the `register` frame is written.
|
|
@@ -255,6 +267,12 @@ class Coordinator {
|
|
|
255
267
|
this._handleWorkerConnection(socket);
|
|
256
268
|
});
|
|
257
269
|
|
|
270
|
+
// Cap concurrent connections so a buggy/malicious local peer can't
|
|
271
|
+
// exhaust our FDs by opening thousands of sockets. Node's net.Server
|
|
272
|
+
// honours this by closing the accepted socket immediately when the
|
|
273
|
+
// count exceeds the limit — request listener never runs.
|
|
274
|
+
this.ipcServer.maxConnections = MAX_WORKER_CONNECTIONS;
|
|
275
|
+
|
|
258
276
|
this.ipcServer.on('error', (err) => {
|
|
259
277
|
reject(err);
|
|
260
278
|
});
|
|
@@ -722,4 +740,5 @@ module.exports = {
|
|
|
722
740
|
LOCK_FILE,
|
|
723
741
|
SOCKET_PATH,
|
|
724
742
|
MAX_IPC_BUFFER,
|
|
743
|
+
MAX_WORKER_CONNECTIONS,
|
|
725
744
|
};
|
package/src/server/web.js
CHANGED
|
@@ -564,7 +564,14 @@ class WebDashboardServer {
|
|
|
564
564
|
try {
|
|
565
565
|
client.write(message);
|
|
566
566
|
} catch (e) {
|
|
567
|
-
//
|
|
567
|
+
// Write failed — proactively prune the dead client instead of
|
|
568
|
+
// waiting for req.on('close') to fire. On abrupt socket resets
|
|
569
|
+
// 'close' can be delayed long enough that subsequent frames
|
|
570
|
+
// hit the same failed write, accumulating exception work and
|
|
571
|
+
// keeping clientCount misleadingly high. Set.delete during
|
|
572
|
+
// iteration is safe; the for-of iterator handles it.
|
|
573
|
+
try { client.end(); } catch (_) { /* already torn down */ }
|
|
574
|
+
this.clients.delete(client);
|
|
568
575
|
}
|
|
569
576
|
}
|
|
570
577
|
}
|