mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
Previously, we ignored all indicators of the body (content-length or transfer-encoding headers) and treated any information following the headers as part of the upgraded stream. We now fully process the requests bodies separately instead, allowing us to automatically handle correct parsing of the body like any other HTTP request. This is a breaking change if you are currently accepting HTTP Upgrade requests with request bodies successfully, or if you use socket-specific fields & methods on the upgraded stream argument. In the former case, before now you will have received the request body and then the upgraded data on the same stream without any distinction or HTTP parsing applied. Now, you will need to separately read the request body from the request (the 1st argument) and the upgraded data from the upgrade stream (the 2nd argument). If you're not interested in request bodies, you can continue to just read from the upgrade stream directly. In the latter case, if you want to access the raw socket, you should do so via request.socket, instead of expecting the 2nd argument to be a socket. PR-URL: https://github.com/nodejs/node/pull/60016 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
47 lines
1.3 KiB
JavaScript
47 lines
1.3 KiB
JavaScript
import * as common from '../common/index.mjs';
|
|
import * as assert from 'assert';
|
|
import * as http from 'http';
|
|
import * as net from 'net';
|
|
|
|
const upgradeReceivedResolvers = Promise.withResolvers();
|
|
|
|
const server = http.createServer();
|
|
server.on('request', common.mustNotCall());
|
|
server.on('upgrade', function(req, socket, upgradeHead) {
|
|
upgradeReceivedResolvers.resolve();
|
|
|
|
// As soon as the body starts arriving, simulate an error
|
|
req.on('data', () => {
|
|
req.socket.destroy(new Error('simulated body error'));
|
|
});
|
|
});
|
|
|
|
await new Promise((resolve) => server.listen(0, () => resolve()));
|
|
|
|
const conn = net.createConnection(server.address().port);
|
|
conn.setEncoding('utf8');
|
|
|
|
await new Promise((resolve) => conn.on('connect', resolve));
|
|
|
|
// Write request headers, leave the body pending:
|
|
conn.write(
|
|
'POST / HTTP/1.1\r\n' +
|
|
'host: localhost\r\n' +
|
|
'Upgrade: custom-protocol\r\n' +
|
|
'Connection: Upgrade\r\n' +
|
|
'transfer-encoding: chunked\r\n' +
|
|
'\r\n'
|
|
);
|
|
|
|
// Make sure the server has processed the above & fired 'upgrade' before the body
|
|
// data starts streaming:
|
|
await upgradeReceivedResolvers.promise;
|
|
|
|
conn.write('5\r\nhello\r\n');
|
|
|
|
process.on('uncaughtException', common.mustCall((err) => {
|
|
assert.strictEqual(err.message, 'simulated body error');
|
|
conn.destroy();
|
|
server.close();
|
|
}));
|