-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
async_wrap: add
asyncReset
to TLSWrap
When using an Agent for HTTPS, `TLSSocket`s are reused and need to have the ability to `asyncReset` from JS. PR-URL: #13092 Fixes: #13045 Reviewed-By: Andreas Madsen <amwebdk@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
- Loading branch information
Showing
2 changed files
with
54 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
'use strict'; | ||
const common = require('../common'); | ||
|
||
// Refs: https://github.com/nodejs/node/issues/13045 | ||
// An HTTP Agent reuses a TLSSocket, and makes a failed call to `asyncReset`. | ||
|
||
const assert = require('assert'); | ||
const https = require('https'); | ||
const fs = require('fs'); | ||
|
||
const serverOptions = { | ||
key: fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`), | ||
cert: fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`), | ||
ca: fs.readFileSync(`${common.fixturesDir}/keys/ca1-cert.pem`) | ||
}; | ||
|
||
const server = https.createServer(serverOptions, common.mustCall((req, res) => { | ||
res.end('hello world\n'); | ||
}, 2)); | ||
|
||
server.listen(0, common.mustCall(function() { | ||
const port = this.address().port; | ||
const clientOptions = { | ||
agent: new https.Agent({ | ||
keepAlive: true, | ||
rejectUnauthorized: false | ||
}), | ||
port: port | ||
}; | ||
|
||
const req = https.get(clientOptions, common.mustCall((res) => { | ||
assert.strictEqual(res.statusCode, 200); | ||
res.on('error', (err) => assert.fail(err)); | ||
res.socket.on('error', (err) => assert.fail(err)); | ||
res.resume(); | ||
// drain the socket and wait for it to be free to reuse | ||
res.socket.once('free', () => { | ||
// This is the pain point. Internally the Agent will call | ||
// `socket._handle.asyncReset()` and if the _handle does not implement | ||
// `asyncReset` this will throw TypeError | ||
const req2 = https.get(clientOptions, common.mustCall((res2) => { | ||
assert.strictEqual(res.statusCode, 200); | ||
res2.on('error', (err) => assert.fail(err)); | ||
res2.socket.on('error', (err) => assert.fail(err)); | ||
// this should be the end of the test | ||
res2.destroy(); | ||
server.close(); | ||
})); | ||
req2.on('error', (err) => assert.fail(err)); | ||
}); | ||
})); | ||
req.on('error', (err) => assert.fail(err)); | ||
})); |