Skip to content

Commit 400442c

Browse files
jpage-godaddyindexzero
authored andcommitted
Support "*" for SNI host pattern (#23)
Fix SNI bug where `*` host pattern generates an invalid RegExp
1 parent f9b9627 commit 400442c

File tree

2 files changed

+64
-49
lines changed

2 files changed

+64
-49
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ function getSNIHandler(sslOpts) {
225225

226226
// Pre-compile regexps for the hostname
227227
var hostRegexps = sniHosts.map(function(host) {
228-
return new RegExp(
228+
return host === '*' ? /.*/ : new RegExp(
229229
'^' +
230230
host
231231
.replace('.', '\\.') // Match dots, not wildcards

test/create-servers-test.js

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -372,55 +372,33 @@ test('supports requestCert https option', function (t) {
372372
});
373373

374374
test('supports SNI', async t => {
375-
t.plan(1);
376-
377-
const hostNames = ['example.com', 'example.net', 'foo.example.org'];
378-
379-
let httpsServer;
380-
try {
381-
const servers = await createServersAsync({
382-
https: {
383-
port: 3456,
384-
root: path.join(__dirname, 'fixtures'),
385-
sni: {
386-
'example.com': {
387-
key: 'example-com-key.pem',
388-
cert: 'example-com-cert.pem'
389-
},
390-
'example.net': {
391-
key: 'example-net-key.pem',
392-
cert: 'example-net-cert.pem'
393-
},
394-
'*.example.org': {
395-
key: 'example-org-key.pem',
396-
cert: 'example-org-cert.pem'
397-
}
398-
}
399-
},
400-
handler: (req, res) => {
401-
res.write('Hello');
402-
res.end();
403-
}
404-
});
405-
httpsServer = servers.https;
406-
407-
hostNames.forEach(host => evilDNS.add(host, '0.0.0.0'));
408-
409-
const responses = await Promise.all(
410-
hostNames.map(hostname => download(`https://${hostname}:3456/`))
411-
);
375+
await testSni(t, {
376+
'example.com': {
377+
key: 'example-com-key.pem',
378+
cert: 'example-com-cert.pem'
379+
},
380+
'example.net': {
381+
key: 'example-net-key.pem',
382+
cert: 'example-net-cert.pem'
383+
},
384+
'*.example.org': {
385+
key: 'example-org-key.pem',
386+
cert: 'example-org-cert.pem'
387+
}
388+
}, ['example.com', 'example.net', 'foo.example.org']);
389+
});
412390

413-
t.equals(
414-
responses.every(str => str === 'Hello'),
415-
true,
416-
'responses are as expected'
417-
);
418-
} catch (err) {
419-
return void t.error(err);
420-
} finally {
421-
httpsServer && httpsServer.close();
422-
evilDNS.clear();
423-
}
391+
test('supports catch-all * for SNI', async t => {
392+
await testSni(t, {
393+
'example.com': {
394+
key: 'example-com-key.pem',
395+
cert: 'example-com-cert.pem'
396+
},
397+
'*': {
398+
key: 'example-org-key.pem',
399+
cert: 'example-org-cert.pem'
400+
}
401+
}, ['example.com', 'foo.example.org']);
424402
});
425403

426404
test('multiple https servers', async function (t) {
@@ -466,3 +444,40 @@ test('multiple https servers', async function (t) {
466444
evilDNS.clear();
467445
}
468446
});
447+
448+
async function testSni(t, sniConfig, hostNames) {
449+
t.plan(1);
450+
451+
let httpsServer;
452+
try {
453+
const servers = await createServersAsync({
454+
https: {
455+
port: 3456,
456+
root: path.join(__dirname, 'fixtures'),
457+
sni: sniConfig
458+
},
459+
handler: (req, res) => {
460+
res.write('Hello');
461+
res.end();
462+
}
463+
});
464+
httpsServer = servers.https;
465+
466+
hostNames.forEach(host => evilDNS.add(host, '0.0.0.0'));
467+
468+
const responses = await Promise.all(
469+
hostNames.map(hostname => download(`https://${hostname}:3456/`))
470+
);
471+
472+
t.equals(
473+
responses.every(str => str === 'Hello'),
474+
true,
475+
'responses are as expected'
476+
);
477+
} catch (err) {
478+
return void t.error(err);
479+
} finally {
480+
httpsServer && httpsServer.close();
481+
evilDNS.clear();
482+
}
483+
}

0 commit comments

Comments
 (0)