• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  mustCall,
5  hasCrypto,
6  hasIPv6,
7  skip,
8  expectsError
9} = require('../common');
10if (!hasCrypto)
11  skip('missing crypto');
12const fixtures = require('../common/fixtures');
13const assert = require('assert');
14const { createServer, createSecureServer, connect } = require('http2');
15const { connect: netConnect } = require('net');
16const { connect: tlsConnect } = require('tls');
17
18// Check for session connect callback and event
19{
20  const server = createServer();
21  server.listen(0, mustCall(() => {
22    const authority = `http://localhost:${server.address().port}`;
23    const options = {};
24    const listener = () => mustCall();
25
26    const clients = new Set();
27    // Should not throw.
28    clients.add(connect(authority));
29    clients.add(connect(authority, options));
30    clients.add(connect(authority, options, listener()));
31    clients.add(connect(authority, listener()));
32
33    for (const client of clients) {
34      client.once('connect', mustCall((headers) => {
35        client.close();
36        clients.delete(client);
37        if (clients.size === 0) {
38          server.close();
39        }
40      }));
41    }
42  }));
43}
44
45// Check for session connect callback on already connected socket
46{
47  const server = createServer();
48  server.listen(0, mustCall(() => {
49    const { port } = server.address();
50
51    const onSocketConnect = () => {
52      const authority = `http://localhost:${port}`;
53      const createConnection = mustCall(() => socket);
54      const options = { createConnection };
55      connect(authority, options, mustCall(onSessionConnect));
56    };
57
58    const onSessionConnect = (session) => {
59      session.close();
60      server.close();
61    };
62
63    const socket = netConnect(port, mustCall(onSocketConnect));
64  }));
65}
66
67// Check for https as protocol
68{
69  const authority = 'https://localhost';
70  // A socket error may or may not be reported, keep this as a non-op
71  // instead of a mustCall or mustNotCall
72  connect(authority).on('error', () => {});
73}
74
75// Check for session connect callback on already connected TLS socket
76{
77  const serverOptions = {
78    key: fixtures.readKey('agent1-key.pem'),
79    cert: fixtures.readKey('agent1-cert.pem')
80  };
81  const server = createSecureServer(serverOptions);
82  server.listen(0, mustCall(() => {
83    const { port } = server.address();
84
85    const onSocketConnect = () => {
86      const authority = `https://localhost:${port}`;
87      const createConnection = mustCall(() => socket);
88      const options = { createConnection };
89      connect(authority, options, mustCall(onSessionConnect));
90    };
91
92    const onSessionConnect = (session) => {
93      session.close();
94      server.close();
95    };
96
97    const clientOptions = {
98      ALPNProtocols: ['h2'],
99      port,
100      rejectUnauthorized: false
101    };
102    const socket = tlsConnect(clientOptions, mustCall(onSocketConnect));
103  }));
104}
105
106// Check for error for init settings error
107{
108  createServer(function() {
109    connect(`http://localhost:${this.address().port}`, {
110      settings: {
111        maxFrameSize: 1   // An incorrect settings
112      }
113    }).on('error', expectsError({
114      code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
115      name: 'RangeError'
116    }));
117  });
118}
119
120// Check for error for an invalid protocol (not http or https)
121{
122  const authority = 'ssh://localhost';
123  assert.throws(() => {
124    connect(authority);
125  }, {
126    code: 'ERR_HTTP2_UNSUPPORTED_PROTOCOL',
127    name: 'Error'
128  });
129}
130
131// Check for literal IPv6 addresses in URL's
132if (hasIPv6) {
133  const server = createServer();
134  server.listen(0, '::1', mustCall(() => {
135    const { port } = server.address();
136    const clients = new Set();
137
138    clients.add(connect(`http://[::1]:${port}`));
139    clients.add(connect(new URL(`http://[::1]:${port}`)));
140
141    for (const client of clients) {
142      client.once('connect', mustCall(() => {
143        client.close();
144        clients.delete(client);
145        if (clients.size === 0) {
146          server.close();
147        }
148      }));
149    }
150  }));
151}
152
153// Check that `options.host` and `options.port` take precedence over
154// `authority.host` and `authority.port`.
155{
156  const server = createServer();
157  server.listen(0, mustCall(() => {
158    connect('http://foo.bar', {
159      host: 'localhost',
160      port: server.address().port
161    }, mustCall((session) => {
162      session.close();
163      server.close();
164    }));
165  }));
166}
167