• 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');
11
12const { kTimeout } = require('internal/timers');
13
14// Tests behavior of the proxied socket in Http2ServerRequest
15// & Http2ServerResponse - this proxy socket should mimic the
16// behavior of http1 but against the http2 api & model
17
18const errMsg = {
19  code: 'ERR_HTTP2_NO_SOCKET_MANIPULATION',
20  name: 'Error',
21  message: 'HTTP/2 sockets should not be directly manipulated ' +
22           '(e.g. read and written)'
23};
24
25const server = h2.createServer();
26
27server.on('request', common.mustCall(function(request, response) {
28  assert.ok(request.socket instanceof net.Socket);
29  assert.ok(response.socket instanceof net.Socket);
30  assert.strictEqual(request.socket, response.socket);
31
32  assert.ok(request.socket.readable);
33  request.resume();
34  assert.ok(request.socket.writable);
35  assert.strictEqual(request.socket.destroyed, false);
36
37  request.socket.setTimeout(987);
38  assert.strictEqual(request.stream.session[kTimeout]._idleTimeout, 987);
39  request.socket.setTimeout(0);
40
41  assert.throws(() => request.socket.read(), errMsg);
42  assert.throws(() => request.socket.write(), errMsg);
43  assert.throws(() => request.socket.pause(), errMsg);
44  assert.throws(() => request.socket.resume(), errMsg);
45
46  // Should have correct this context for socket methods & getters
47  assert.ok(request.socket.address() != null);
48  assert.ok(request.socket.remotePort);
49
50  request.on('end', common.mustCall(() => {
51    assert.strictEqual(request.socket.readable, false);
52    response.socket.destroy();
53  }));
54  response.on('finish', common.mustCall(() => {
55    assert.ok(request.socket);
56    assert.strictEqual(response.socket, undefined);
57    assert.ok(request.socket.destroyed);
58    assert.strictEqual(request.socket.readable, false);
59    process.nextTick(() => {
60      assert.strictEqual(request.socket.writable, false);
61      server.close();
62    });
63  }));
64
65  // Properties that do not exist on the proxy are retrieved from the socket
66  assert.ok(request.socket._server);
67  assert.strictEqual(request.socket.connecting, false);
68
69  // Socket events are bound and emitted on Http2Stream
70  request.socket.on('close', common.mustCall());
71  request.socket.once('close', common.mustCall());
72  request.socket.on('testEvent', common.mustCall());
73  request.socket.emit('testEvent');
74}));
75
76server.listen(0, common.mustCall(function() {
77  const port = server.address().port;
78  const url = `http://localhost:${port}`;
79  const client = h2.connect(url, common.mustCall(() => {
80    const headers = {
81      ':path': '/',
82      ':method': 'GET',
83      ':scheme': 'http',
84      ':authority': `localhost:${port}`
85    };
86    const request = client.request(headers);
87    request.on('end', common.mustCall(() => {
88      client.close();
89    }));
90    request.end();
91    request.resume();
92  }));
93}));
94