Skip to content

Commit 20cba8a

Browse files
committed
[test] http2 options
1 parent f9a48b5 commit 20cba8a

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

test/create-servers-test.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var path = require('path'),
1010
url = require('url'),
1111
http = require('http'),
1212
https = require('https'),
13+
http2 = require('http2'),
1314
{ promisify } = require('util'),
1415
test = require('tape'),
1516
sinon = require('sinon'),
@@ -18,6 +19,8 @@ var path = require('path'),
1819

1920
const createServersAsync = promisify(createServers);
2021

22+
const { HTTP2_HEADER_PATH } = http2.constants;
23+
2124
const ca = fs.readFileSync(path.join(__dirname, './fixtures/example-ca-cert.pem'));
2225

2326
//
@@ -50,6 +53,74 @@ async function download(httpsURL) {
5053
});
5154
}
5255

56+
//
57+
// Request and download response from a URL using HTTP/2
58+
//
59+
async function download2(httpsURL) {
60+
return new Promise((resolve, reject) => {
61+
const clientSession = http2.connect(httpsURL);
62+
const fail = results => {
63+
clientSession.close();
64+
reject(results);
65+
};
66+
67+
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
68+
req.on('response', () => {
69+
const chunks = [];
70+
req
71+
.on('data', chunk => chunks.push(chunk))
72+
.once('end', () => {
73+
resolve(chunks.map(chunk => chunk.toString('utf8')).join(''));
74+
clientSession.close();
75+
});
76+
})
77+
.once('aborted', fail)
78+
.once('close', fail)
79+
.once('error', fail);
80+
});
81+
}
82+
83+
/**
84+
* Helper to start a server with HTTP/2 support.
85+
* Returns stop function to handle server and dns cleanup after tests.
86+
*
87+
* Tests requests can be made to foo.example.org:3456
88+
*
89+
* @param {object} options - Additional http2 server options.
90+
* @returns {Promise<(function(): void)|*>} callback
91+
*/
92+
async function startHttp2Server(options = {}) {
93+
// disabling to avoid UNABLE_TO_VERIFY_LEAF_SIGNATURE for tests
94+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
95+
96+
const servers = await createServersAsync({
97+
http2: {
98+
port: 3456,
99+
root: path.join(__dirname, 'fixtures'),
100+
key: 'example-org-key.pem',
101+
cert: 'example-org-cert.pem',
102+
...options
103+
},
104+
handler: (req, res) => {
105+
const { httpVersion } = req;
106+
const { socket: { alpnProtocol } } = httpVersion === '2.0' ? req.stream.session : req;
107+
res.writeHead(200, { 'content-type': 'application/json' });
108+
res.end(JSON.stringify({
109+
alpnProtocol,
110+
httpVersion
111+
}));
112+
}
113+
});
114+
115+
evilDNS.add('foo.example.org', '0.0.0.0');
116+
117+
return function stop() {
118+
servers && servers.http2 && servers.http2.close();
119+
evilDNS.clear();
120+
delete process.env.NODE_TLS_REJECT_UNAUTHORIZED;
121+
};
122+
}
123+
53124
test('only http', function (t) {
54125
t.plan(5);
55126
createServers({
@@ -145,6 +216,28 @@ test('only https', function (t) {
145216
});
146217
});
147218

219+
test('only http2', function (t) {
220+
t.plan(4);
221+
var time = 4000000;
222+
createServers({
223+
log: console.log,
224+
http2: {
225+
timeout: time,
226+
port: 3456,
227+
root: path.join(__dirname, 'fixtures'),
228+
key: 'example-org-key.pem',
229+
cert: 'example-org-cert.pem'
230+
},
231+
handler: fend
232+
}, function (err, servers) {
233+
t.error(err);
234+
t.equals(typeof servers, 'object');
235+
t.equals(typeof servers.http2, 'object');
236+
t.equals(servers.http2.timeout, time);
237+
servers.http2.close();
238+
});
239+
});
240+
148241
test('absolute cert path resolution', function (t) {
149242
t.plan(3);
150243
createServers({
@@ -445,6 +538,50 @@ test('multiple https servers', async function (t) {
445538
}
446539
});
447540

541+
test('supports http2-only requests', async function (t) {
542+
t.plan(2);
543+
const url = 'https://foo.example.org:3456/';
544+
545+
let stopServer;
546+
try {
547+
stopServer = await startHttp2Server({});
548+
549+
const httpsResponse = await download(url);
550+
t.ok(httpsResponse.includes('Unknown ALPN Protocol'));
551+
552+
const response = JSON.parse(await download2(url));
553+
t.equals(response.httpVersion, '2.0');
554+
555+
} catch (err) {
556+
t.error(err);
557+
} finally {
558+
stopServer && stopServer();
559+
}
560+
});
561+
562+
test('supports http2 and https requests', async function (t) {
563+
t.plan(2);
564+
const url = 'https://foo.example.org:3456/';
565+
566+
let stopServer;
567+
try {
568+
stopServer = await startHttp2Server({
569+
allowHTTP1: true
570+
});
571+
572+
const httpsResponse = JSON.parse(await download(url));
573+
t.equals(httpsResponse.httpVersion, '1.1');
574+
575+
const response = JSON.parse(await download2(url));
576+
t.equals(response.httpVersion, '2.0');
577+
578+
} catch (err) {
579+
t.error(err);
580+
} finally {
581+
stopServer && stopServer();
582+
}
583+
});
584+
448585
async function testSni(t, sniConfig, hostNames) {
449586
t.plan(1);
450587

0 commit comments

Comments
 (0)