Skip to content

Commit 90d7821

Browse files
authored
fix: wait a macrotick to resume without pipelining (nodejs#1465)
* Wait a macrotick to resume without pipelining This change makes the Client wait for a full macrotick before executing up the next request if pipelining is disabled. This is to account for socket errors events that might be waiting to be processed in the event queue. This is the expected behavior without pipelining. This will slow us down a bit without pipelinig. Fixes: nodejs#1415 Signed-off-by: Matteo Collina <[email protected]> * fixup Signed-off-by: Matteo Collina <[email protected]>
1 parent 4684a15 commit 90d7821

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

lib/client.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,11 @@ class Parser {
873873
// have been queued since then.
874874
util.destroy(socket, new InformationalError('reset'))
875875
return constants.ERROR.PAUSED
876+
} else if (client[kPipelining] === 1) {
877+
// We must wait a full event loop cycle to reuse this socket to make sure
878+
// that non-spec compliant servers are not closing the connection even if they
879+
// said they won't.
880+
setImmediate(resume, client)
876881
} else {
877882
resume(client)
878883
}

test/inflight-and-close.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict'
2+
3+
const t = require('tap')
4+
const { request } = require('..')
5+
const http = require('http')
6+
7+
const server = http.createServer((req, res) => {
8+
res.writeHead(200)
9+
res.end('Response body')
10+
res.socket.end() // Close the connection immediately with every response
11+
}).listen(0, '127.0.0.1', function () {
12+
const url = `http://127.0.0.1:${this.address().port}`
13+
request(url)
14+
.then(({ statusCode, headers, body }) => {
15+
t.pass('first response')
16+
body.resume()
17+
body.on('close', function () {
18+
t.pass('first body closed')
19+
})
20+
return request(url)
21+
.then(({ statusCode, headers, body }) => {
22+
t.pass('second response')
23+
body.resume()
24+
body.on('close', function () {
25+
server.close()
26+
})
27+
})
28+
}).catch((err) => {
29+
t.error(err)
30+
})
31+
})

0 commit comments

Comments
 (0)