11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciif (!common.hasCrypto)
51cb0ef41Sopenharmony_ci  common.skip('missing crypto');
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst h2 = require('http2');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci// Push a request & response
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst pushExpect = 'This is a server-initiated response';
121cb0ef41Sopenharmony_ciconst servExpect = 'This is a client-initiated response';
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst server = h2.createServer((request, response) => {
151cb0ef41Sopenharmony_ci  assert.strictEqual(response.stream.id % 2, 1);
161cb0ef41Sopenharmony_ci  response.write(servExpect);
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci  // Callback must be specified (and be a function)
191cb0ef41Sopenharmony_ci  assert.throws(
201cb0ef41Sopenharmony_ci    () => response.createPushResponse({
211cb0ef41Sopenharmony_ci      ':path': '/pushed',
221cb0ef41Sopenharmony_ci      ':method': 'GET'
231cb0ef41Sopenharmony_ci    }, undefined),
241cb0ef41Sopenharmony_ci    {
251cb0ef41Sopenharmony_ci      code: 'ERR_INVALID_ARG_TYPE',
261cb0ef41Sopenharmony_ci      name: 'TypeError',
271cb0ef41Sopenharmony_ci    }
281cb0ef41Sopenharmony_ci  );
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  response.stream.on('close', () => {
311cb0ef41Sopenharmony_ci    response.createPushResponse({
321cb0ef41Sopenharmony_ci      ':path': '/pushed',
331cb0ef41Sopenharmony_ci      ':method': 'GET'
341cb0ef41Sopenharmony_ci    }, common.mustCall((error) => {
351cb0ef41Sopenharmony_ci      assert.strictEqual(error.code, 'ERR_HTTP2_INVALID_STREAM');
361cb0ef41Sopenharmony_ci    }));
371cb0ef41Sopenharmony_ci  });
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  response.createPushResponse({
401cb0ef41Sopenharmony_ci    ':path': '/pushed',
411cb0ef41Sopenharmony_ci    ':method': 'GET'
421cb0ef41Sopenharmony_ci  }, common.mustSucceed((push) => {
431cb0ef41Sopenharmony_ci    assert.strictEqual(push.stream.id % 2, 0);
441cb0ef41Sopenharmony_ci    push.end(pushExpect);
451cb0ef41Sopenharmony_ci    response.end();
461cb0ef41Sopenharmony_ci  }));
471cb0ef41Sopenharmony_ci});
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => {
501cb0ef41Sopenharmony_ci  const port = server.address().port;
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci  const client = h2.connect(`http://localhost:${port}`, common.mustCall(() => {
531cb0ef41Sopenharmony_ci    const headers = {
541cb0ef41Sopenharmony_ci      ':path': '/',
551cb0ef41Sopenharmony_ci      ':method': 'GET',
561cb0ef41Sopenharmony_ci    };
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci    let remaining = 2;
591cb0ef41Sopenharmony_ci    function maybeClose() {
601cb0ef41Sopenharmony_ci      if (--remaining === 0) {
611cb0ef41Sopenharmony_ci        client.close();
621cb0ef41Sopenharmony_ci        server.close();
631cb0ef41Sopenharmony_ci      }
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    const req = client.request(headers);
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci    client.on('stream', common.mustCall((pushStream, headers) => {
691cb0ef41Sopenharmony_ci      assert.strictEqual(headers[':path'], '/pushed');
701cb0ef41Sopenharmony_ci      assert.strictEqual(headers[':method'], 'GET');
711cb0ef41Sopenharmony_ci      assert.strictEqual(headers[':scheme'], 'http');
721cb0ef41Sopenharmony_ci      assert.strictEqual(headers[':authority'], `localhost:${port}`);
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci      let actual = '';
751cb0ef41Sopenharmony_ci      pushStream.on('push', common.mustCall((headers) => {
761cb0ef41Sopenharmony_ci        assert.strictEqual(headers[':status'], 200);
771cb0ef41Sopenharmony_ci        assert(headers.date);
781cb0ef41Sopenharmony_ci      }));
791cb0ef41Sopenharmony_ci      pushStream.setEncoding('utf8');
801cb0ef41Sopenharmony_ci      pushStream.on('data', (chunk) => actual += chunk);
811cb0ef41Sopenharmony_ci      pushStream.on('end', common.mustCall(() => {
821cb0ef41Sopenharmony_ci        assert.strictEqual(actual, pushExpect);
831cb0ef41Sopenharmony_ci        maybeClose();
841cb0ef41Sopenharmony_ci      }));
851cb0ef41Sopenharmony_ci    }));
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci    req.on('response', common.mustCall((headers) => {
881cb0ef41Sopenharmony_ci      assert.strictEqual(headers[':status'], 200);
891cb0ef41Sopenharmony_ci      assert(headers.date);
901cb0ef41Sopenharmony_ci    }));
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    let actual = '';
931cb0ef41Sopenharmony_ci    req.setEncoding('utf8');
941cb0ef41Sopenharmony_ci    req.on('data', (chunk) => actual += chunk);
951cb0ef41Sopenharmony_ci    req.on('end', common.mustCall(() => {
961cb0ef41Sopenharmony_ci      assert.strictEqual(actual, servExpect);
971cb0ef41Sopenharmony_ci      maybeClose();
981cb0ef41Sopenharmony_ci    }));
991cb0ef41Sopenharmony_ci  }));
1001cb0ef41Sopenharmony_ci}));
101