| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 613be79 commit 6c3516f
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -278,10 +278,17 @@ function maybeEnableKeylog(eventName) { | |||
| 278 | 278 | this[kOnKeylog] = function onkeylog(keylog) { | |
| 279 | 279 | agent.emit('keylog', keylog, this); | |
| 280 | 280 | }; | |
| 281 | - // Existing sockets will start listening on keylog now. | ||
| 282 | - const sockets = ObjectValues(this.sockets); | ||
| 283 | - for (let i = 0; i < sockets.length; i++) { | ||
| 284 | - sockets[i].on('keylog', this[kOnKeylog]); | ||
| 281 | + // Existing sockets will start listening on keylog now. Both maps hold | ||
| 282 | + // arrays of sockets keyed by name, so each bucket has to be walked. | ||
| 283 | + const sets = [this.freeSockets, this.sockets]; | ||
| 284 | + for (let s = 0; s < sets.length; s++) { | ||
| 285 | + const buckets = ObjectValues(sets[s]); | ||
| 286 | + for (let b = 0; b < buckets.length; b++) { | ||
| 287 | + const sockets = buckets[b]; | ||
| 288 | + for (let n = 0; n < sockets.length; n++) { | ||
| 289 | + sockets[n].on('keylog', this[kOnKeylog]); | ||
| 290 | + } | ||
| 291 | + } | ||
| 285 | 292 | } | |
| 286 | 293 | } | |
| 287 | 294 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,71 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const http = require('http'); | ||
| 6 | + | ||
| 7 | + // Adding a 'keylog' listener to an agent is wired up by maybeEnableKeylog(), | ||
| 8 | + // which attaches the agent's keylog handler to the sockets the agent already | ||
| 9 | + // owns. `agent.sockets` and `agent.freeSockets` map a name to an *array* of | ||
| 10 | + // sockets, so each bucket has to be walked. Treating the buckets themselves as | ||
| 11 | + // sockets threw a TypeError out of `agent.on('keylog', ...)`, which also meant | ||
| 12 | + // the listener was never registered. | ||
| 13 | + | ||
| 14 | + // Two servers so the two sockets get different names, which keeps one parked | ||
| 15 | + // in freeSockets instead of being reused by the second request. | ||
| 16 | + const idleServer = http.createServer((req, res) => res.end('idle')); | ||
| 17 | + const busyServer = http.createServer((req, res) => { | ||
| 18 | + setTimeout(() => res.end('busy'), common.platformTimeout(200)); | ||
| 19 | + }); | ||
| 20 | + | ||
| 21 | + function countSockets(agent) { | ||
| 22 | + let free = 0; | ||
| 23 | + let active = 0; | ||
| 24 | + for (const bucket of Object.values(agent.freeSockets)) free += bucket.length; | ||
| 25 | + for (const bucket of Object.values(agent.sockets)) active += bucket.length; | ||
| 26 | + return { free, active }; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + idleServer.listen(0, common.mustCall(() => { | ||
| 30 | + busyServer.listen(0, common.mustCall(() => { | ||
| 31 | + const agent = new http.Agent({ keepAlive: true, maxSockets: 4 }); | ||
| 32 | + | ||
| 33 | + // First request finishes, so its socket is released into freeSockets. | ||
| 34 | + http.get({ port: idleServer.address().port, agent }, common.mustCall((res) => { | ||
| 35 | + res.resume(); | ||
| 36 | + res.on('end', common.mustCall(() => { | ||
| 37 | + // Second request is still in flight, so its socket is in sockets. | ||
| 38 | + const req = http.get({ port: busyServer.address().port, agent }, | ||
| 39 | + common.mustCall((res2) => { | ||
| 40 | + res2.resume(); | ||
| 41 | + res2.on('end', common.mustCall(() => { | ||
| 42 | + agent.destroy(); | ||
| 43 | + idleServer.close(); | ||
| 44 | + busyServer.close(); | ||
| 45 | + })); | ||
| 46 | + })); | ||
| 47 | + | ||
| 48 | + req.on('socket', common.mustCall(() => { | ||
| 49 | + setImmediate(common.mustCall(() => { | ||
| 50 | + const { free, active } = countSockets(agent); | ||
| 51 | + assert.strictEqual(free, 1); | ||
| 52 | + assert.strictEqual(active, 1); | ||
| 53 | + | ||
| 54 | + // Used to throw `TypeError: sockets[i].on is not a function`. | ||
| 55 | + agent.on('keylog', common.mustNotCall()); | ||
| 56 | + assert.strictEqual(agent.listenerCount('keylog'), 1); | ||
| 57 | + | ||
| 58 | + // Every existing socket, idle or in use, is now listening. | ||
| 59 | + for (const set of [agent.freeSockets, agent.sockets]) { | ||
| 60 | + for (const bucket of Object.values(set)) { | ||
| 61 | + for (const socket of bucket) { | ||
| 62 | + assert.strictEqual(socket.listenerCount('keylog'), 1); | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + })); | ||
| 67 | + })); | ||
| 68 | + })); | ||
| 69 | + })); | ||
| 70 | + })); | ||
| 71 | + })); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments