1'use strict';
2const common = require('../common');
3if (!common.hasCrypto)
4  common.skip('missing crypto');
5
6const assert = require('assert');
7const net = require('net');
8const http = require('http');
9const http2 = require('http2');
10
11// Example test for HTTP/1 vs HTTP/2 protocol autoselection.
12// Refs: https://github.com/nodejs/node/issues/34532
13
14const h1Server = http.createServer(common.mustCall((req, res) => {
15  res.end('HTTP/1 Response');
16}));
17
18const h2Server = http2.createServer(common.mustCall((req, res) => {
19  res.end('HTTP/2 Response');
20}));
21
22const rawServer = net.createServer(common.mustCall(function listener(socket) {
23  const data = socket.read(3);
24
25  if (!data) { // Repeat until data is available
26    socket.once('readable', () => listener(socket));
27    return;
28  }
29
30  // Put the data back, so the real server can handle it:
31  socket.unshift(data);
32
33  if (data.toString('ascii') === 'PRI') { // Very dumb preface check
34    h2Server.emit('connection', socket);
35  } else {
36    h1Server.emit('connection', socket);
37  }
38}, 2));
39
40rawServer.listen(common.mustCall(() => {
41  const { port } = rawServer.address();
42
43  let done = 0;
44  {
45    // HTTP/2 Request
46    const client = http2.connect(`http://localhost:${port}`);
47    const req = client.request({ ':path': '/' });
48    req.end();
49
50    let content = '';
51    req.setEncoding('utf8');
52    req.on('data', (chunk) => content += chunk);
53    req.on('end', common.mustCall(() => {
54      assert.strictEqual(content, 'HTTP/2 Response');
55      if (++done === 2) rawServer.close();
56      client.close();
57    }));
58  }
59
60  {
61    // HTTP/1 Request
62    http.get(`http://localhost:${port}`, common.mustCall((res) => {
63      let content = '';
64      res.setEncoding('utf8');
65      res.on('data', (chunk) => content += chunk);
66      res.on('end', common.mustCall(() => {
67        assert.strictEqual(content, 'HTTP/1 Response');
68        if (++done === 2) rawServer.close();
69      }));
70    }));
71  }
72}));
73