1'use strict';
2
3// Verifies that a full HTTP2 pipeline handles backpressure.
4
5const common = require('../common');
6if (!common.hasCrypto)
7  common.skip('missing crypto');
8const assert = require('assert');
9const http2 = require('http2');
10const makeDuplexPair = require('../common/duplexpair');
11
12{
13  let req;
14  const server = http2.createServer();
15  server.on('stream', mustCallAsync(async (stream, headers) => {
16    stream.respond({
17      'content-type': 'text/html',
18      ':status': 200
19    });
20    req._readableState.highWaterMark = 20;
21    stream._writableState.highWaterMark = 20;
22    assert.strictEqual(stream.write('A'.repeat(5)), true);
23    assert.strictEqual(stream.write('A'.repeat(40)), false);
24    assert.strictEqual(await event(req, 'data'), 'A'.repeat(5));
25    assert.strictEqual(await event(req, 'data'), 'A'.repeat(40));
26    await event(stream, 'drain');
27    assert.strictEqual(stream.write('A'.repeat(5)), true);
28    assert.strictEqual(stream.write('A'.repeat(40)), false);
29  }));
30
31  const { clientSide, serverSide } = makeDuplexPair();
32  server.emit('connection', serverSide);
33
34  const client = http2.connect('http://localhost:80', {
35    createConnection: common.mustCall(() => clientSide)
36  });
37
38  req = client.request({ ':path': '/' });
39  req.setEncoding('utf8');
40  req.end();
41}
42
43function event(ee, eventName) {
44  return new Promise((resolve) => {
45    ee.once(eventName, common.mustCall(resolve));
46  });
47}
48
49function mustCallAsync(fn, exact) {
50  return common.mustCall((...args) => {
51    return Promise.resolve(fn(...args)).then(common.mustCall((val) => val));
52  }, exact);
53}
54