test: guard write to proxy client if proxy connection is ended

In the testing proxy server for proxy client tests, the proxy
client might have already closed the connection when the upstream
connection fails. In that case, there's no need for the proxy
server to inform the proxy client about the error.

PR-URL: https://github.com/nodejs/node/pull/59742
Fixes: https://github.com/nodejs/node/issues/59741
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Joyee Cheung
2025-09-17 15:59:09 +02:00
committed by GitHub
parent c46260284c
commit 5c7b83a94e
2 changed files with 25 additions and 15 deletions

View File

@@ -21,9 +21,10 @@ const server = https.createServer({
cert: fixtures.readKey('agent8-cert.pem'),
key: fixtures.readKey('agent8-key.pem'),
}, (req, res) => {
console.log(`[Upstream server] responding to request for ${inspect(req.url)}`);
requests.add(`https://localhost:${server.address().port}${req.url}`);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Response for ${req.url}`);
res.end(`Response for ${inspect(req.url)}`);
});
server.listen(0);
@@ -54,7 +55,7 @@ https.globalAgent = new https.Agent({
const severHost = `localhost:${server.address().port}`;
let counter = testCases.length;
let counter = 0;
const expectedUrls = new Set();
const expectedProxyLogs = new Set();
for (const testCase of testCases) {
@@ -69,15 +70,20 @@ for (const testCase of testCases) {
https.request(url, (res) => {
res.on('error', common.mustNotCall());
res.setEncoding('utf8');
res.on('data', () => {});
res.on('end', common.mustCall(() => {
console.log(`#${counter--} eneded response for: ${inspect(url)}`);
res.on('data', (data) => {
console.log(`[Proxy client] Received response from server for ${inspect(url)}: ${data.toString()}`);
});
res.on('close', common.mustCall(() => {
console.log(`[Proxy client] #${++counter} closed request for: ${inspect(url)}`);
// Finished all test cases.
if (counter === 0) {
proxy.close();
server.close();
assert.deepStrictEqual(requests, expectedUrls);
assert.deepStrictEqual(new Set(logs), expectedProxyLogs);
if (counter === testCases.length) {
setImmediate(() => {
console.log('All requests completed, shutting down.');
proxy.close();
server.close();
assert.deepStrictEqual(requests, expectedUrls);
assert.deepStrictEqual(new Set(logs), expectedProxyLogs);
});
}
}));
}).on('error', common.mustNotCall()).end();

View File

@@ -63,7 +63,7 @@ exports.createProxyServer = function(options = {}) {
});
res.on('error', (err) => {
logs.push({ error: err, source: 'proxy response' });
logs.push({ error: err, source: 'client response for request' });
});
req.pipe(proxyReq, { end: true });
@@ -75,7 +75,7 @@ exports.createProxyServer = function(options = {}) {
const [hostname, port] = req.url.split(':');
res.on('error', (err) => {
logs.push({ error: err, source: 'proxy response' });
logs.push({ error: err, source: 'client response for connect' });
});
const proxyReq = net.connect(port, hostname, () => {
@@ -90,9 +90,13 @@ exports.createProxyServer = function(options = {}) {
});
proxyReq.on('error', (err) => {
logs.push({ error: err, source: 'proxy request' });
res.write('HTTP/1.1 500 Connection Error\r\n\r\n');
res.end('Proxy error: ' + err.message);
logs.push({ error: err, source: 'proxy connect' });
// The proxy client might have already closed the connection
// when the upstream connection fails.
if (!res.writableEnded) {
res.write('HTTP/1.1 500 Connection Error\r\n\r\n');
res.end('Proxy error: ' + err.message);
}
});
});