Skip to content

Commit 82f6c1e

Browse files
committed
Add tests for trailers & chunk extensions too
1 parent be61c60 commit 82f6c1e

File tree

4 files changed

+95
-6
lines changed

4 files changed

+95
-6
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import * as common from '../common/index.mjs';
2+
import * as assert from 'assert';
3+
import * as http from 'http';
4+
import * as net from 'net';
5+
6+
const EXPECTED_BODY_LENGTH = 12;
7+
8+
const upgradeReceivedResolvers = Promise.withResolvers();
9+
10+
const server = http.createServer();
11+
server.on('request', common.mustNotCall());
12+
server.on('upgrade', function(req, socket, upgradeHead) {
13+
upgradeReceivedResolvers.resolve();
14+
15+
// Confirm the upgrade:
16+
socket.write('HTTP/1.1 101 Switching Protocols\r\n' +
17+
'Upgrade: custom-protocol\r\n' +
18+
'Connection: Upgrade\r\n' +
19+
'\r\n');
20+
21+
// Read and validate the request body:
22+
let reqBodyLength = 0;
23+
req.on('data', (chunk) => { reqBodyLength += chunk.length; });
24+
req.on('end', common.mustCall(() => {
25+
assert.strictEqual(reqBodyLength, EXPECTED_BODY_LENGTH);
26+
27+
assert.deepStrictEqual(req.trailers, { 'extra-data': 'abc' });
28+
29+
// Defer upgrade stream read slightly to make sure it doesn't start
30+
// streaming along with the request body, until we actually read it:
31+
setTimeout(common.mustCall(() => {
32+
let socketData = upgradeHead;
33+
34+
socket.on('data', (d) => {
35+
socketData = Buffer.concat([socketData, d]);
36+
});
37+
38+
socket.on('end', common.mustCall(() => {
39+
assert.strictEqual(socketData.toString(), 'upgrade head\npost-upgrade message');
40+
socket.end();
41+
}));
42+
}), 10);
43+
}));
44+
});
45+
46+
await new Promise((resolve) => server.listen(0, () => resolve()));
47+
48+
const conn = net.createConnection(server.address().port);
49+
conn.setEncoding('utf8');
50+
51+
await new Promise((resolve) => conn.on('connect', resolve));
52+
53+
// Write request headers, body & upgrade head all together
54+
conn.write(
55+
'POST / HTTP/1.1\r\n' +
56+
'host: localhost\r\n' +
57+
'Upgrade: custom-protocol\r\n' +
58+
'Connection: Upgrade\r\n' +
59+
'transfer-encoding: chunked\r\n' +
60+
'trailer: extra-data\r\n' +
61+
'\r\n'
62+
);
63+
64+
// Make sure the server has processed the above & fired 'upgrade', before the body
65+
// data starts streaming:
66+
await upgradeReceivedResolvers.promise;
67+
68+
// Write the body, and include a chunk extension and a trailer header to check
69+
// that upgrade handling doesn't skip or confuse anything with request parsing:
70+
conn.write(
71+
// 12 byte body sent immediately, with (ignored) chunk extension.
72+
'C;chunk-hash=abc\r\nrequest body\r\n' +
73+
'0\r\n' +
74+
// Request trailer:
75+
'extra-data: abc\r\n' +
76+
'\r\n' +
77+
'upgrade head'
78+
);
79+
80+
const response = await new Promise((resolve) => conn.once('data', resolve));
81+
assert.ok(response.startsWith('HTTP/1.1 101 Switching Protocols\r\n'));
82+
83+
// Send more data after connection is confirmed:
84+
conn.write('\npost-upgrade message');
85+
conn.end();
86+
87+
await new Promise((resolve) => conn.on('end', resolve));
88+
89+
server.close();

test/parallel/test-http-upgrade-server-with-body.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ server.on('upgrade', function(req, socket, upgradeHead) {
2525
setTimeout(common.mustCall(() => {
2626
let socketData = upgradeHead;
2727

28-
socket.on('data', common.mustCall((d) => {
28+
socket.on('data', (d) => {
2929
socketData = Buffer.concat([socketData, d]);
30-
}));
30+
});
3131

3232
socket.on('end', common.mustCall(() => {
3333
assert.strictEqual(socketData.toString(), 'upgrade head\npost-upgrade message');

test/parallel/test-http-upgrade-server-with-large-body-unread.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ server.on('upgrade', function(req, socket, upgradeHead) {
2929

3030
// Collect the raw upgrade stream and check we do eventually get the
3131
// complete stream:
32-
socket.on('data', common.mustCall((d) => {
32+
socket.on('data', (d) => {
3333
socketData = Buffer.concat([socketData, d]);
34-
}));
34+
});
3535

3636
socket.on('end', common.mustCall(() => {
3737
assert.strictEqual(socketData.toString(), 'upgrade head\npost-upgrade message');

test/parallel/test-http-upgrade-server-with-large-body.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ server.on('upgrade', function(req, socket, upgradeHead) {
3636

3737
// Start streaming the raw upgrade stream immediately as well, and check we do
3838
// eventually get the complete stream:
39-
socket.on('data', common.mustCall((d) => {
39+
socket.on('data', (d) => {
4040
socketData = Buffer.concat([socketData, d]);
41-
}));
41+
});
4242

4343
socket.on('end', common.mustCall(() => {
4444
assert.strictEqual(socketData.toString(), 'upgrade head\npost-upgrade message');

0 commit comments

Comments
 (0)