1'use strict'; 2const common = require('../common'); 3 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6 7const assert = require('assert'); 8const tls = require('tls'); 9const fixtures = require('../common/fixtures'); 10 11function loadPEM(n) { 12 return fixtures.readKey(`${n}.pem`); 13} 14 15const serverIP = common.localhostIPv4; 16 17function checkResults(result, expected) { 18 assert.strictEqual(result.server.ALPN, expected.server.ALPN); 19 assert.strictEqual(result.client.ALPN, expected.client.ALPN); 20} 21 22function runTest(clientsOptions, serverOptions, cb) { 23 serverOptions.key = loadPEM('agent2-key'); 24 serverOptions.cert = loadPEM('agent2-cert'); 25 const results = []; 26 let clientIndex = 0; 27 let serverIndex = 0; 28 const server = tls.createServer(serverOptions, function(c) { 29 results[serverIndex++].server = { ALPN: c.alpnProtocol }; 30 }); 31 32 server.listen(0, serverIP, function() { 33 connectClient(clientsOptions); 34 }); 35 36 function connectClient(options) { 37 const opt = options.shift(); 38 opt.port = server.address().port; 39 opt.host = serverIP; 40 opt.rejectUnauthorized = false; 41 42 results[clientIndex] = {}; 43 const client = tls.connect(opt, function() { 44 results[clientIndex].client = { ALPN: client.alpnProtocol }; 45 client.end(); 46 if (options.length) { 47 clientIndex++; 48 connectClient(options); 49 } else { 50 server.close(); 51 server.on('close', () => { 52 cb(results); 53 }); 54 } 55 }); 56 } 57 58} 59 60// Server: ALPN, Client: ALPN 61function Test1() { 62 const serverOptions = { 63 ALPNProtocols: ['a', 'b', 'c'], 64 }; 65 66 const clientsOptions = [{ 67 ALPNProtocols: ['a', 'b', 'c'], 68 }, { 69 ALPNProtocols: ['c', 'b', 'e'], 70 }, { 71 ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], 72 }]; 73 74 runTest(clientsOptions, serverOptions, function(results) { 75 // 'a' is selected by ALPN 76 checkResults(results[0], 77 { server: { ALPN: 'a' }, 78 client: { ALPN: 'a' } }); 79 // 'b' is selected by ALPN 80 checkResults(results[1], 81 { server: { ALPN: 'b' }, 82 client: { ALPN: 'b' } }); 83 // Nothing is selected by ALPN 84 checkResults(results[2], 85 { server: { ALPN: false }, 86 client: { ALPN: false } }); 87 // execute next test 88 Test2(); 89 }); 90} 91 92// Server: ALPN, Client: Nothing 93function Test2() { 94 const serverOptions = { 95 ALPNProtocols: ['a', 'b', 'c'], 96 }; 97 98 const clientsOptions = [{}, {}, {}]; 99 100 runTest(clientsOptions, serverOptions, function(results) { 101 // Nothing is selected by ALPN 102 checkResults(results[0], 103 { server: { ALPN: false }, 104 client: { ALPN: false } }); 105 // Nothing is selected by ALPN 106 checkResults(results[1], 107 { server: { ALPN: false }, 108 client: { ALPN: false } }); 109 // Nothing is selected by ALPN 110 checkResults(results[2], 111 { server: { ALPN: false }, 112 client: { ALPN: false } }); 113 // execute next test 114 Test3(); 115 }); 116} 117 118// Server: Nothing, Client: ALPN 119function Test3() { 120 const serverOptions = {}; 121 122 const clientsOptions = [{ 123 ALPNrotocols: ['a', 'b', 'c'], 124 }, { 125 ALPNProtocols: ['c', 'b', 'e'], 126 }, { 127 ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], 128 }]; 129 130 runTest(clientsOptions, serverOptions, function(results) { 131 // nothing is selected 132 checkResults(results[0], { server: { ALPN: false }, 133 client: { ALPN: false } }); 134 // nothing is selected 135 checkResults(results[1], { server: { ALPN: false }, 136 client: { ALPN: false } }); 137 // nothing is selected 138 checkResults(results[2], 139 { server: { ALPN: false }, 140 client: { ALPN: false } }); 141 // execute next test 142 Test4(); 143 }); 144} 145 146// Server: Nothing, Client: Nothing 147function Test4() { 148 const serverOptions = {}; 149 150 const clientsOptions = [{}, {}, {}]; 151 152 runTest(clientsOptions, serverOptions, function(results) { 153 // nothing is selected 154 checkResults(results[0], { server: { ALPN: false }, 155 client: { ALPN: false } }); 156 // nothing is selected 157 checkResults(results[1], { server: { ALPN: false }, 158 client: { ALPN: false } }); 159 // nothing is selected 160 checkResults(results[2], 161 { server: { ALPN: false }, 162 client: { ALPN: false } }); 163 }); 164} 165 166Test1(); 167