New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[v8.x] http: attach reused parser to correct domain #25459
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const domain = require('domain'); | ||
const http = require('http'); | ||
|
||
const agent = new http.Agent({ | ||
// keepAlive is important here so that the underlying socket of all requests | ||
// is reused and tied to the same domain. | ||
keepAlive: true | ||
}); | ||
|
||
function performHttpRequest(opts, cb) { | ||
const req = http.get({ port: server.address().port, agent }, (res) => { | ||
// Consume the data from the response to make sure the 'end' event is | ||
// emitted. | ||
res.on('data', function noop() {}); | ||
res.on('end', () => { | ||
if (opts.shouldThrow) { | ||
throw new Error('boom'); | ||
} else { | ||
cb(); | ||
} | ||
}); | ||
|
||
res.on('error', (resErr) => { | ||
process.exit(1); | ||
}); | ||
|
||
}).on('error', (reqErr) => { | ||
process.exit(1); | ||
}); | ||
|
||
req.end(); | ||
} | ||
|
||
function performHttpRequestInNewDomain(opts, cb) { | ||
const d = domain.create(); | ||
d._id = opts.id; | ||
d.run(() => { | ||
performHttpRequest(opts, cb); | ||
}); | ||
|
||
return d; | ||
} | ||
|
||
const server = http.createServer((req, res) => { | ||
res.end(); | ||
}); | ||
|
||
server.listen(0, common.mustCall(function() { | ||
const d1 = performHttpRequestInNewDomain({ | ||
shouldThrow: false | ||
}, common.mustCall((firstReqErr) => { | ||
// We want to schedule the second request on the next turn of the event | ||
// loop so that the parser from the first request is actually reused. | ||
setImmediate(common.mustCall(() => { | ||
const d2 = performHttpRequestInNewDomain({ | ||
shouldThrow: true | ||
}, (secondReqErr) => { | ||
// Since this request throws before its callback has the chance | ||
// to be called, we mark the test as failed if this callback is | ||
// called. | ||
process.exit(1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the only reason for this is to mark the test as failed, I’d prefer setting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, i'll do both! |
||
}); | ||
|
||
// The second request throws when its response's end event is | ||
// emitted. So we expect its domain to emit an error event. | ||
d2.on('error', common.mustCall((d2err) => { | ||
server.close(); | ||
}, 1)); | ||
})); | ||
})); | ||
|
||
d1.on('error', (d1err) => { | ||
// d1 is the domain attached to the first request, which doesn't throw, | ||
// so we don't expect its error handler to be called. | ||
process.exit(1); | ||
}); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have an assertion that checks that the connection is the same for all requests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
Instead of an assertion, which can throw an exception and thus trigger a different code path with regards to domain error handling that would make this test really difficult to write, do you mind if, as for other failure cases in this test, we set the exit code to 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@misterdjules Yes, that sounds good to me as well :)