hapi
hapi copied to clipboard
vhost routing with http2 (and TLS) does not work
Support plan
- is this issue currently blocking your project? (yes/no): yes
- is this issue affecting a production system? (yes/no): no
Context
- node version: v19.0.0
- module version with issue: ^20.2.2
- last module version without issue: -
- environment (e.g. node, browser, native): node
- used with (e.g. hapi application, another framework, standalone, ...): -
- any other relevant information: -
What are you trying to achieve or the steps to reproduce?
import hapi from '@hapi/hapi'
import {createSecureServer} from 'node:http2'
import {dirname, join} from 'node:path'
import {fileURLToPath} from 'node:url'
import { readFileSync } from 'node:fs'
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
let app = {}
let http2Settings = {
headerTableSize: 4096,
enablePush: true,
initialWindowSize: 65535,
maxFrameSize: 16384,
maxConcurrentStreams: 4294967295,
maxHeaderListSize: 65535,
enableConnectProtocol: false
}
let secureServerOptions = {
allowHTTP1: true,
/* maxDeflateDynamicTableSize, */
maxSettings: 32,
maxSessionMemory: 10,
maxHeaderListPairs: 128,
maxOutstandingPings: 10,
/* maxSendHeaderBlockLength, */
/* paddingStrategy, */
peerMaxConcurrentStreams: 100,
maxSessionInvalidFrames: 1000,
maxSessionRejectedStreams: 100,
settings: http2Settings
}
let secureServer = createSecureServer(secureServerOptions)
const cipherValueIntermediate = 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'
const cipher = cipherValueIntermediate
const minVersion = 'TLSv1.2'
const maxVersion = 'TLSv1.3'
const dhparam = readFileSync(join(__dirname, '/security/dhparam.pem'))
const ecdhCurve = 'auto'
const honorCipherOrder = false
let context = {
/* ca, */
cert: readFileSync(join(__dirname, '/letsencrypt/live/example.com/fullchain.pem')),
key: readFileSync(join(__dirname, '/letsencrypt/live/example.com/privkey.pem')),
cipher,
minVersion,
maxVersion,
dhparam,
ecdhCurve,
honorCipherOrder
}
let context2 = {
/* ca, */
cert: readFileSync(join(__dirname, '/letsencrypt/live/api.example.com/fullchain.pem')),
key: readFileSync(join(__dirname, '/letsencrypt/live/api.example.com/privkey.pem')),
cipher,
minVersion,
maxVersion,
dhparam,
ecdhCurve,
honorCipherOrder
}
secureServer.addContext('example.com', context)
secureServer.addContext('api.example.com', context2)
async function vhostBug(app) {
let serverOptions = {
address: '0.0.0.0',
app,
listener: secureServer,
autoListen: true,
tls: true,
port: 443
}
let hapiServer = hapi.Server(serverOptions)
await hapiServer.start()
// vhost example.com
// does not work
hapiServer.route({
method: 'GET',
path: '/',
vhost: 'example.com',
handler: function (request, h) {
return 'example.com'
}
})
// vhost api.example.com
// does not work
hapiServer.route({
method: 'GET',
path: '/',
vhost: 'api.example.com',
handler: function (request, h) {
return 'api.example.com'
}
})
// no vhost
// works for both api.example.com and example.com
hapiServer.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return '*.example.com'
}
})
}
vhostBug(app)
What was the result you got?
The routes with vhost in use under http2 are not served. The routes do not match. With an http context it works well (TLS disabled).
What result did you expect?
Working vhost routes as expected.