11cb0ef41Sopenharmony_ci// Flags: --expose-internals
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci'use strict';
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciif (!common.hasCrypto)
71cb0ef41Sopenharmony_ci  common.skip('missing crypto');
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst h2 = require('http2');
101cb0ef41Sopenharmony_ciconst net = require('net');
111cb0ef41Sopenharmony_ciconst util = require('util');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciconst { kTimeout } = require('internal/timers');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Tests behavior of the proxied socket on Http2Session
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciconst errMsg = {
181cb0ef41Sopenharmony_ci  code: 'ERR_HTTP2_NO_SOCKET_MANIPULATION',
191cb0ef41Sopenharmony_ci  name: 'Error',
201cb0ef41Sopenharmony_ci  message: 'HTTP/2 sockets should not be directly manipulated ' +
211cb0ef41Sopenharmony_ci           '(e.g. read and written)'
221cb0ef41Sopenharmony_ci};
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciconst server = h2.createServer();
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciserver.on('stream', common.mustCall(function(stream, headers) {
271cb0ef41Sopenharmony_ci  const socket = stream.session.socket;
281cb0ef41Sopenharmony_ci  const session = stream.session;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  assert.ok(socket instanceof net.Socket);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  assert.strictEqual(socket.writable, true);
331cb0ef41Sopenharmony_ci  assert.strictEqual(socket.readable, true);
341cb0ef41Sopenharmony_ci  assert.strictEqual(typeof socket.address(), 'object');
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  socket.setTimeout(987);
371cb0ef41Sopenharmony_ci  assert.strictEqual(session[kTimeout]._idleTimeout, 987);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  // The indentation is corrected depending on the depth.
401cb0ef41Sopenharmony_ci  let inspectedTimeout = util.inspect(session[kTimeout]);
411cb0ef41Sopenharmony_ci  assert(inspectedTimeout.includes('  _idlePrev: [TimersList]'));
421cb0ef41Sopenharmony_ci  assert(inspectedTimeout.includes('  _idleNext: [TimersList]'));
431cb0ef41Sopenharmony_ci  assert(!inspectedTimeout.includes('   _idleNext: [TimersList]'));
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  inspectedTimeout = util.inspect([ session[kTimeout] ]);
461cb0ef41Sopenharmony_ci  assert(inspectedTimeout.includes('    _idlePrev: [TimersList]'));
471cb0ef41Sopenharmony_ci  assert(inspectedTimeout.includes('    _idleNext: [TimersList]'));
481cb0ef41Sopenharmony_ci  assert(!inspectedTimeout.includes('     _idleNext: [TimersList]'));
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  const inspectedTimersList = util.inspect([[ session[kTimeout]._idlePrev ]]);
511cb0ef41Sopenharmony_ci  assert(inspectedTimersList.includes('      _idlePrev: [Timeout]'));
521cb0ef41Sopenharmony_ci  assert(inspectedTimersList.includes('      _idleNext: [Timeout]'));
531cb0ef41Sopenharmony_ci  assert(!inspectedTimersList.includes('       _idleNext: [Timeout]'));
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  assert.throws(() => socket.destroy, errMsg);
561cb0ef41Sopenharmony_ci  assert.throws(() => socket.emit, errMsg);
571cb0ef41Sopenharmony_ci  assert.throws(() => socket.end, errMsg);
581cb0ef41Sopenharmony_ci  assert.throws(() => socket.pause, errMsg);
591cb0ef41Sopenharmony_ci  assert.throws(() => socket.read, errMsg);
601cb0ef41Sopenharmony_ci  assert.throws(() => socket.resume, errMsg);
611cb0ef41Sopenharmony_ci  assert.throws(() => socket.write, errMsg);
621cb0ef41Sopenharmony_ci  assert.throws(() => socket.setEncoding, errMsg);
631cb0ef41Sopenharmony_ci  assert.throws(() => socket.setKeepAlive, errMsg);
641cb0ef41Sopenharmony_ci  assert.throws(() => socket.setNoDelay, errMsg);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  assert.throws(() => (socket.destroy = undefined), errMsg);
671cb0ef41Sopenharmony_ci  assert.throws(() => (socket.emit = undefined), errMsg);
681cb0ef41Sopenharmony_ci  assert.throws(() => (socket.end = undefined), errMsg);
691cb0ef41Sopenharmony_ci  assert.throws(() => (socket.pause = undefined), errMsg);
701cb0ef41Sopenharmony_ci  assert.throws(() => (socket.read = undefined), errMsg);
711cb0ef41Sopenharmony_ci  assert.throws(() => (socket.resume = undefined), errMsg);
721cb0ef41Sopenharmony_ci  assert.throws(() => (socket.write = undefined), errMsg);
731cb0ef41Sopenharmony_ci  assert.throws(() => (socket.setEncoding = undefined), errMsg);
741cb0ef41Sopenharmony_ci  assert.throws(() => (socket.setKeepAlive = undefined), errMsg);
751cb0ef41Sopenharmony_ci  assert.throws(() => (socket.setNoDelay = undefined), errMsg);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  // Resetting the socket listeners to their own value should not throw.
781cb0ef41Sopenharmony_ci  socket.on = socket.on;  // eslint-disable-line no-self-assign
791cb0ef41Sopenharmony_ci  socket.once = socket.once;  // eslint-disable-line no-self-assign
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci  socket.unref();
821cb0ef41Sopenharmony_ci  assert.strictEqual(socket._handle.hasRef(), false);
831cb0ef41Sopenharmony_ci  socket.ref();
841cb0ef41Sopenharmony_ci  assert.strictEqual(socket._handle.hasRef(), true);
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  stream.respond();
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  socket.writable = true;
891cb0ef41Sopenharmony_ci  socket.readable = true;
901cb0ef41Sopenharmony_ci  assert.strictEqual(socket.writable, true);
911cb0ef41Sopenharmony_ci  assert.strictEqual(socket.readable, true);
921cb0ef41Sopenharmony_ci  socket.writable = false;
931cb0ef41Sopenharmony_ci  socket.readable = false;
941cb0ef41Sopenharmony_ci  assert.strictEqual(socket.writable, false);
951cb0ef41Sopenharmony_ci  assert.strictEqual(socket.readable, false);
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  stream.end();
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  // Setting socket properties sets the session properties correctly.
1001cb0ef41Sopenharmony_ci  const fn = () => {};
1011cb0ef41Sopenharmony_ci  socket.setTimeout = fn;
1021cb0ef41Sopenharmony_ci  assert.strictEqual(session.setTimeout, fn);
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  socket.ref = fn;
1051cb0ef41Sopenharmony_ci  assert.strictEqual(session.ref, fn);
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  socket.unref = fn;
1081cb0ef41Sopenharmony_ci  assert.strictEqual(session.unref, fn);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  stream.session.on('close', common.mustCall(() => {
1111cb0ef41Sopenharmony_ci    assert.strictEqual(session.socket, undefined);
1121cb0ef41Sopenharmony_ci  }));
1131cb0ef41Sopenharmony_ci}));
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(function() {
1161cb0ef41Sopenharmony_ci  const port = server.address().port;
1171cb0ef41Sopenharmony_ci  const url = `http://localhost:${port}`;
1181cb0ef41Sopenharmony_ci  const client = h2.connect(url, common.mustCall(() => {
1191cb0ef41Sopenharmony_ci    const request = client.request();
1201cb0ef41Sopenharmony_ci    request.on('end', common.mustCall(() => {
1211cb0ef41Sopenharmony_ci      client.close();
1221cb0ef41Sopenharmony_ci      server.close();
1231cb0ef41Sopenharmony_ci    }));
1241cb0ef41Sopenharmony_ci    request.resume();
1251cb0ef41Sopenharmony_ci  }));
1261cb0ef41Sopenharmony_ci}));
127