• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-internals
2
3'use strict';
4
5const common = require('../common');
6if (!common.hasCrypto)
7  common.skip('missing crypto');
8const assert = require('assert');
9const h2 = require('http2');
10const net = require('net');
11const util = require('util');
12
13const { kTimeout } = require('internal/timers');
14
15// Tests behavior of the proxied socket on Http2Session
16
17const errMsg = {
18  code: 'ERR_HTTP2_NO_SOCKET_MANIPULATION',
19  name: 'Error',
20  message: 'HTTP/2 sockets should not be directly manipulated ' +
21           '(e.g. read and written)'
22};
23
24const server = h2.createServer();
25
26server.on('stream', common.mustCall(function(stream, headers) {
27  const socket = stream.session.socket;
28  const session = stream.session;
29
30  assert.ok(socket instanceof net.Socket);
31
32  assert.strictEqual(socket.writable, true);
33  assert.strictEqual(socket.readable, true);
34  assert.strictEqual(typeof socket.address(), 'object');
35
36  socket.setTimeout(987);
37  assert.strictEqual(session[kTimeout]._idleTimeout, 987);
38
39  // The indentation is corrected depending on the depth.
40  let inspectedTimeout = util.inspect(session[kTimeout]);
41  assert(inspectedTimeout.includes('  _idlePrev: [TimersList]'));
42  assert(inspectedTimeout.includes('  _idleNext: [TimersList]'));
43  assert(!inspectedTimeout.includes('   _idleNext: [TimersList]'));
44
45  inspectedTimeout = util.inspect([ session[kTimeout] ]);
46  assert(inspectedTimeout.includes('    _idlePrev: [TimersList]'));
47  assert(inspectedTimeout.includes('    _idleNext: [TimersList]'));
48  assert(!inspectedTimeout.includes('     _idleNext: [TimersList]'));
49
50  const inspectedTimersList = util.inspect([[ session[kTimeout]._idlePrev ]]);
51  assert(inspectedTimersList.includes('      _idlePrev: [Timeout]'));
52  assert(inspectedTimersList.includes('      _idleNext: [Timeout]'));
53  assert(!inspectedTimersList.includes('       _idleNext: [Timeout]'));
54
55  assert.throws(() => socket.destroy, errMsg);
56  assert.throws(() => socket.emit, errMsg);
57  assert.throws(() => socket.end, errMsg);
58  assert.throws(() => socket.pause, errMsg);
59  assert.throws(() => socket.read, errMsg);
60  assert.throws(() => socket.resume, errMsg);
61  assert.throws(() => socket.write, errMsg);
62  assert.throws(() => socket.setEncoding, errMsg);
63  assert.throws(() => socket.setKeepAlive, errMsg);
64  assert.throws(() => socket.setNoDelay, errMsg);
65
66  assert.throws(() => (socket.destroy = undefined), errMsg);
67  assert.throws(() => (socket.emit = undefined), errMsg);
68  assert.throws(() => (socket.end = undefined), errMsg);
69  assert.throws(() => (socket.pause = undefined), errMsg);
70  assert.throws(() => (socket.read = undefined), errMsg);
71  assert.throws(() => (socket.resume = undefined), errMsg);
72  assert.throws(() => (socket.write = undefined), errMsg);
73  assert.throws(() => (socket.setEncoding = undefined), errMsg);
74  assert.throws(() => (socket.setKeepAlive = undefined), errMsg);
75  assert.throws(() => (socket.setNoDelay = undefined), errMsg);
76
77  // Resetting the socket listeners to their own value should not throw.
78  socket.on = socket.on;  // eslint-disable-line no-self-assign
79  socket.once = socket.once;  // eslint-disable-line no-self-assign
80
81  socket.unref();
82  assert.strictEqual(socket._handle.hasRef(), false);
83  socket.ref();
84  assert.strictEqual(socket._handle.hasRef(), true);
85
86  stream.respond();
87
88  socket.writable = 0;
89  socket.readable = 0;
90  assert.strictEqual(socket.writable, 0);
91  assert.strictEqual(socket.readable, 0);
92
93  stream.end();
94
95  // Setting socket properties sets the session properties correctly.
96  const fn = () => {};
97  socket.setTimeout = fn;
98  assert.strictEqual(session.setTimeout, fn);
99
100  socket.ref = fn;
101  assert.strictEqual(session.ref, fn);
102
103  socket.unref = fn;
104  assert.strictEqual(session.unref, fn);
105
106  stream.session.on('close', common.mustCall(() => {
107    assert.strictEqual(session.socket, undefined);
108  }));
109}));
110
111server.listen(0, common.mustCall(function() {
112  const port = server.address().port;
113  const url = `http://localhost:${port}`;
114  const client = h2.connect(url, common.mustCall(() => {
115    const request = client.request();
116    request.on('end', common.mustCall(() => {
117      client.close();
118      server.close();
119    }));
120    request.resume();
121  }));
122}));
123