Skip to content

Commit

Permalink
fix(#3817): send servername for SNI on TLS (#3821)
Browse files Browse the repository at this point in the history
* fix(#3817): send servername for SNI on TLS

* fix: set host header to servername

* refactor: attach regardless
  • Loading branch information
metcoder95 authored Nov 20, 2024
1 parent 08065c0 commit b93a834
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 2 deletions.
10 changes: 8 additions & 2 deletions lib/interceptor/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,15 @@ module.exports = interceptorOpts => {
return handler.onError(err)
}

const dispatchOpts = {
let dispatchOpts = null
dispatchOpts = {
...origDispatchOpts,
origin: newOrigin
servername: origin.hostname, // For SNI on TLS
origin: newOrigin,
headers: {
host: origin.hostname,
...origDispatchOpts.headers
}
}

dispatch(
Expand Down
89 changes: 89 additions & 0 deletions test/interceptors/dns.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ const { test, after } = require('node:test')
const { isIP } = require('node:net')
const { lookup } = require('node:dns')
const { createServer } = require('node:http')
const { createServer: createSecureServer } = require('node:https')
const { once } = require('node:events')
const { setTimeout: sleep } = require('node:timers/promises')

const { tspl } = require('@matteo.collina/tspl')
const pem = require('https-pem')

const { interceptors, Agent } = require('../..')
const { dns } = interceptors
Expand Down Expand Up @@ -108,6 +110,93 @@ test('Should automatically resolve IPs (dual stack)', async t => {
t.equal(await response2.body.text(), 'hello world!')
})

test('Should respect DNS origin hostname for SNI on TLS', async t => {
t = tspl(t, { plan: 12 })

const hostsnames = []
const server = createSecureServer(pem)
const requestOptions = {
method: 'GET',
path: '/',
headers: {
'content-type': 'application/json'
}
}

server.on('request', (req, res) => {
t.equal(req.headers.host, 'localhost')
res.writeHead(200, { 'content-type': 'text/plain' })
res.end('hello world!')
})

server.listen(0)

await once(server, 'listening')

const client = new Agent({
connect: {
rejectUnauthorized: false
}
}).compose([
dispatch => {
return (opts, handler) => {
const url = new URL(opts.origin)

t.equal(hostsnames.includes(url.hostname), false)
t.equal(opts.servername, 'localhost')

if (url.hostname[0] === '[') {
// [::1] -> ::1
t.equal(isIP(url.hostname.slice(1, 4)), 6)
} else {
t.equal(isIP(url.hostname), 4)
}

hostsnames.push(url.hostname)

return dispatch(opts, handler)
}
},
dns({
lookup: (_origin, _opts, cb) => {
cb(null, [
{
address: '::1',
family: 6
},
{
address: '127.0.0.1',
family: 4
}
])
}
})
])

after(async () => {
await client.close()
server.close()

await once(server, 'close')
})

const response = await client.request({
...requestOptions,
origin: `https://localhost:${server.address().port}`
})

t.equal(response.statusCode, 200)
t.equal(await response.body.text(), 'hello world!')

const response2 = await client.request({
...requestOptions,
origin: `https://localhost:${server.address().port}`
})

t.equal(response2.statusCode, 200)
t.equal(await response2.body.text(), 'hello world!')
})

test('Should recover on network errors (dual stack - 4)', async t => {
t = tspl(t, { plan: 8 })

Expand Down

0 comments on commit b93a834

Please sign in to comment.