Skip to content

Commit

Permalink
feat: add custom undici instance (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
dnlup authored Oct 1, 2021
1 parent 2b69985 commit f996385
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 9 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,17 @@ proxy.register(require('fastify-reply-from'), {
}
})
```

See undici own options for more configurations.

You can also pass the plugin a custom instance:

```js
proxy.register(require('fastify-reply-from'), {
base: 'http://localhost:3001/',
undici: new undici.Pool('http://localhost:3001')
})
```

#### `http`

Set the `http` option to `true` or to an Object to use
Expand Down
24 changes: 16 additions & 8 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ function shouldUseUndici (opts) {
return true
}

function isUndiciInstance (obj) {
return obj instanceof undici.Pool ||
obj instanceof undici.Client ||
obj instanceof undici.Dispatcher
}

function buildRequest (opts) {
const isHttp2 = !!opts.http2
const isUndici = shouldUseUndici(opts)
const hasUndiciOptions = shouldUseUndici(opts)
const requests = {
'http:': http,
'https:': https,
Expand All @@ -33,7 +39,7 @@ function buildRequest (opts) {
const undiciOpts = opts.undici || {}
let http2Client
let undiciAgent
let undiciPool
let undiciInstance
let agents

if (isHttp2) {
Expand All @@ -53,12 +59,14 @@ function buildRequest (opts) {

if (isHttp2) {
return { request: handleHttp2Req, close, retryOnError: 'ECONNRESET' }
} else if (isUndici) {
} else if (hasUndiciOptions) {
if (opts.base && opts.base.startsWith('unix+')) {
const undiciOpts = getUndiciOptions(opts.undici)
undiciOpts.socketPath = decodeURIComponent(new URL(opts.base).host)
const protocol = opts.base.startsWith('unix+https') ? 'https' : 'http'
undiciPool = new undici.Pool(protocol + '://localhost', undiciOpts)
undiciInstance = new undici.Pool(protocol + '://localhost', undiciOpts)
} else if (isUndiciInstance(opts.undici)) {
undiciInstance = opts.undici
} else {
undiciAgent = new undici.Agent(getUndiciOptions(opts.undici))
}
Expand All @@ -68,9 +76,9 @@ function buildRequest (opts) {
}

function close () {
if (isUndici) {
if (hasUndiciOptions) {
undiciAgent && undiciAgent.destroy()
undiciPool && undiciPool.destroy()
undiciInstance && undiciInstance.destroy()
} else if (!isHttp2) {
agents['http:'].destroy()
agents['https:'].destroy()
Expand Down Expand Up @@ -114,8 +122,8 @@ function buildRequest (opts) {

let pool

if (undiciPool) {
pool = undiciPool
if (undiciInstance) {
pool = undiciInstance
} else if (!baseUrl && opts.url.protocol.startsWith('unix')) {
done(new Error('unix socket not supported with undici yet'))
return
Expand Down
77 changes: 77 additions & 0 deletions test/custom-undici-instance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use strict'

const t = require('tap')
const Fastify = require('fastify')
const undici = require('undici')
const http = require('http')
const get = require('simple-get').concat
const From = require('..')

const target = http.createServer((req, res) => {
t.pass('request proxied')
t.equal(req.method, 'GET')
t.equal(req.url, '/')
t.equal(req.headers.connection, 'keep-alive')
res.statusCode = 205
res.setHeader('Content-Type', 'text/plain')
res.setHeader('x-my-header', 'hello!')
res.end('hello world')
})

t.test('use a custom instance of \'undici\'', async t => {
t.teardown(target.close.bind(target))

await new Promise((resolve, reject) => target.listen(0, err => err ? reject(err) : resolve()))

t.test('custom Pool', t => {
const instance = Fastify()
t.teardown(instance.close.bind(instance))
instance.register(From, {
base: `http://localhost:${target.address().port}`,
undici: new undici.Pool(`http://localhost:${target.address().port}`)
})

instance.get('/', (request, reply) => {
reply.from()
})

instance.listen(0, (err) => {
t.error(err)

get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
t.error(err)
t.equal(res.headers['content-type'], 'text/plain')
t.equal(res.headers['x-my-header'], 'hello!')
t.equal(res.statusCode, 205)
t.equal(data.toString(), 'hello world')
t.end()
})
})
})

t.test('custom Client', t => {
const instance = Fastify()
t.teardown(instance.close.bind(instance))
instance.register(From, {
base: `http://localhost:${target.address().port}`,
undici: new undici.Client(`http://localhost:${target.address().port}`)
})

instance.get('/', (request, reply) => {
reply.from()
})

instance.listen(0, (err) => {
t.error(err)

get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
t.error(err)
t.equal(res.headers['content-type'], 'text/plain')
t.equal(res.headers['x-my-header'], 'hello!')
t.equal(res.statusCode, 205)
t.equal(data.toString(), 'hello world')
t.end()
})
})
})
})

0 comments on commit f996385

Please sign in to comment.