mirror of
https://github.com/nodejs/node.git
synced 2025-05-09 07:27:32 +00:00

PR-URL: https://github.com/nodejs/node/pull/17406 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> This is a significant cleanup and refactoring of the cleanup/close/destroy logic for Http2Stream and Http2Session. There are significant changes here in the timing and ordering of cleanup logic, JS apis. and various related necessary edits.
105 lines
3.0 KiB
JavaScript
105 lines
3.0 KiB
JavaScript
'use strict';
|
|
|
|
// This test ensures that servers are able to send data independent of window
|
|
// size.
|
|
// TODO: This test makes large buffer allocations (128KiB) and should be tested
|
|
// on smaller / IoT platforms in case this poses problems for these targets.
|
|
|
|
const common = require('../common');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
const assert = require('assert');
|
|
const h2 = require('http2');
|
|
common.crashOnUnhandledRejection();
|
|
|
|
// Given a list of buffers and an initial window size, have a server write
|
|
// each buffer to the HTTP2 Writable stream, and let the client verify that
|
|
// all of the bytes were sent correctly
|
|
function run(buffers, initialWindowSize) {
|
|
return new Promise((resolve, reject) => {
|
|
const expectedBuffer = Buffer.concat(buffers);
|
|
|
|
const server = h2.createServer();
|
|
server.on('stream', (stream) => {
|
|
let i = 0;
|
|
const writeToStream = () => {
|
|
const cont = () => {
|
|
i++;
|
|
if (i < buffers.length) {
|
|
setImmediate(writeToStream);
|
|
} else {
|
|
stream.end();
|
|
}
|
|
};
|
|
const drained = stream.write(buffers[i]);
|
|
if (drained) {
|
|
cont();
|
|
} else {
|
|
stream.once('drain', cont);
|
|
}
|
|
};
|
|
writeToStream();
|
|
});
|
|
server.listen(0);
|
|
|
|
server.on('listening', common.mustCall(function() {
|
|
const port = this.address().port;
|
|
|
|
const client =
|
|
h2.connect({
|
|
authority: 'localhost',
|
|
protocol: 'http:',
|
|
port
|
|
}, {
|
|
settings: {
|
|
initialWindowSize
|
|
}
|
|
}).on('connect', common.mustCall(() => {
|
|
const req = client.request({
|
|
':method': 'GET',
|
|
':path': '/'
|
|
});
|
|
const responses = [];
|
|
req.on('data', (data) => {
|
|
responses.push(data);
|
|
});
|
|
req.on('end', common.mustCall(() => {
|
|
const actualBuffer = Buffer.concat(responses);
|
|
assert.strictEqual(Buffer.compare(actualBuffer, expectedBuffer), 0);
|
|
// shut down
|
|
client.close();
|
|
server.close(() => {
|
|
resolve();
|
|
});
|
|
}));
|
|
req.end();
|
|
}));
|
|
}));
|
|
});
|
|
}
|
|
|
|
const bufferValueRange = [0, 1, 2, 3];
|
|
const buffersList = [
|
|
bufferValueRange.map((a) => Buffer.alloc(1 << 4, a)),
|
|
bufferValueRange.map((a) => Buffer.alloc((1 << 8) - 1, a)),
|
|
// Specifying too large of a value causes timeouts on some platforms
|
|
// bufferValueRange.map((a) => Buffer.alloc(1 << 17, a))
|
|
];
|
|
const initialWindowSizeList = [
|
|
1 << 4,
|
|
(1 << 8) - 1,
|
|
1 << 8,
|
|
1 << 17,
|
|
undefined // use default window size which is (1 << 16) - 1
|
|
];
|
|
|
|
// Call `run` on each element in the cartesian product of buffersList and
|
|
// initialWindowSizeList.
|
|
let p = Promise.resolve();
|
|
for (const buffers of buffersList) {
|
|
for (const initialWindowSize of initialWindowSizeList) {
|
|
p = p.then(() => run(buffers, initialWindowSize));
|
|
}
|
|
}
|
|
p.then(common.mustCall(() => {}));
|