From 123dccd16a3051de0d368b56656727a50cb01aa6 Mon Sep 17 00:00:00 2001 From: Jun Mukai Date: Tue, 2 May 2017 11:31:03 -0700 Subject: [PATCH] http2: specify default TLS options for http2 client connection. fixes: https://github.com/nodejs/http2/issues/59 Also, add a testcase for http2/TLS secure connection. This verifies to send the server name and ALPN protocols by default. PR-URL: https://github.com/nodejs/http2/pull/61 Reviewed-By: Matteo Collina Reviewed-By: James M Snell --- lib/internal/http2/core.js | 7 +- ...test-http2-create-client-secure-session.js | 66 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100755 test/parallel/test-http2-create-client-secure-session.js diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 3e14dc0336..64455da9a9 100755 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -1091,10 +1091,13 @@ function initializeOptions(options) { return options; } -function initializeTLSOptions(options) { +function initializeTLSOptions(options, servername) { options = initializeOptions(options); options.ALPNProtocols = ['hc', 'h2']; options.NPNProtocols = ['hc', 'h2']; + if (servername !== undefined) { + options.servername = servername; + } return options; } @@ -1242,7 +1245,7 @@ function connect(authority, options, listener) { socket = net.connect(port, host); break; case 'https:': - socket = tls.connect(port, host, options); + socket = tls.connect(port, host, initializeTLSOptions(options, host)); break; default: throw new TypeError(`protocol "${protocol}" in unsupported.`); diff --git a/test/parallel/test-http2-create-client-secure-session.js b/test/parallel/test-http2-create-client-secure-session.js new file mode 100755 index 0000000000..52f66fbec8 --- /dev/null +++ b/test/parallel/test-http2-create-client-secure-session.js @@ -0,0 +1,66 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const tls = require('tls'); +const h2 = require('http2'); +const body = + '

this is some data

'; + +const key = loadKey('agent8-key.pem'); +const cert = loadKey('agent8-cert.pem'); +const ca = loadKey('fake-startcom-root-cert.pem'); + +function loadKey(keyname) { + return fs.readFileSync(path.join(common.fixturesDir, 'keys', keyname), 'binary'); +} + +const server = h2.createSecureServer({cert, key}); + +// we use the lower-level API here +server.on('stream', common.mustCall(onStream)); + +function onStream(stream) { + stream.respond({ + 'content-type': 'text/html', + ':status': 200 + }); + const socket = stream.session.socket; + stream.end(JSON.stringify({ + servername: socket.servername, + alpnProtocol: socket.alpnProtocol + })); +} + +server.listen(0); + +server.on('listening', common.mustCall(function() { + + const headers = { ':path': '/' }; + + const clientOptions = {secureContext: tls.createSecureContext({ca})}; + const client = h2.connect(`https://localhost:${this.address().port}`, clientOptions, function() { + const req = client.request(headers); + + req.on('response', common.mustCall(function(headers) { + assert.strictEqual(headers[':status'], '200', 'status code is set'); + assert.strictEqual(headers['content-type'], 'text/html', + 'content type is set'); + assert(headers['date'], 'there is a date'); + })); + + let data = ''; + req.setEncoding('utf8'); + req.on('data', (d) => data += d); + req.on('end', common.mustCall(() => { + const jsonData = JSON.parse(data); + assert.strictEqual(jsonData.servername, 'localhost'); + assert(jsonData.alpnProtocol === 'h2' || jsonData.alpnProtocol === 'hc'); + server.close(); + client.socket.destroy(); + })); + req.end(); + }); +}));