Skip to content

Commit bab12aa

Browse files
authored
feat: Add preRewrite and routes options. (#422)
1 parent 2265155 commit bab12aa

File tree

3 files changed

+79
-17
lines changed

3 files changed

+79
-17
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ Note that the [rewriteHeaders](https://github.com/fastify/fastify-reply-from#rew
193193

194194
An array that contains the types of the methods. Default: `['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']`.
195195

196+
### `routes`
197+
198+
An array that contains the routes to handle. Default: `['/', '/*']`.
199+
200+
### `preRewrite`
201+
202+
A function that will be executed before rewriting the URL. It receives the URL, the request parameters and the prefix and must return the new URL.
203+
204+
The function cannot return a promise.
205+
196206
### `websocket`
197207

198208
This module has _partial_ support for forwarding websockets by passing a

index.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const fp = require('fastify-plugin')
88
const qs = require('fast-querystring')
99
const { validateOptions } = require('./src/options')
1010

11-
const httpMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
11+
const defaultRoutes = ['/', '/*']
12+
const defaultHttpMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
1213
const urlPattern = /^https?:\/\//
1314
const kWs = Symbol('ws')
1415
const kWsHead = Symbol('wsHead')
@@ -82,6 +83,10 @@ function isExternalUrl (url) {
8283

8384
function noop () { }
8485

86+
function noopPreRewrite (url) {
87+
return url
88+
}
89+
8590
function createContext (logger) {
8691
return { log: logger }
8792
}
@@ -518,6 +523,7 @@ async function fastifyHttpProxy (fastify, opts) {
518523
opts = validateOptions(opts)
519524

520525
const preHandler = opts.preHandler || opts.beforeHandler
526+
const preRewrite = typeof opts.preRewrite === 'function' ? opts.preRewrite : noopPreRewrite
521527
const rewritePrefix = generateRewritePrefix(fastify.prefix, opts)
522528

523529
const fromOpts = Object.assign({}, opts)
@@ -555,22 +561,13 @@ async function fastifyHttpProxy (fastify, opts) {
555561
done(null, payload)
556562
}
557563

558-
fastify.route({
559-
url: '/',
560-
method: opts.httpMethods || httpMethods,
561-
preHandler,
562-
config: opts.config || {},
563-
constraints: opts.constraints || {},
564-
handler
565-
})
566-
fastify.route({
567-
url: '/*',
568-
method: opts.httpMethods || httpMethods,
569-
preHandler,
570-
config: opts.config || {},
571-
constraints: opts.constraints || {},
572-
handler
573-
})
564+
const method = opts.httpMethods || defaultHttpMethods
565+
const config = opts.config || {}
566+
const constraints = opts.constraints || {}
567+
568+
for (const url of opts.routes || defaultRoutes) {
569+
fastify.route({ url, method, preHandler, config, constraints, handler })
570+
}
574571

575572
let wsProxy
576573

@@ -593,6 +590,8 @@ async function fastifyHttpProxy (fastify, opts) {
593590
}
594591

595592
function fromParameters (url, params = {}, prefix = '/') {
593+
url = preRewrite(url, params, prefix)
594+
596595
const { path, queryParams } = extractUrlComponents(url)
597596
let dest = path
598597

@@ -646,4 +645,6 @@ module.exports = fp(fastifyHttpProxy, {
646645
encapsulate: true
647646
})
648647
module.exports.default = fastifyHttpProxy
648+
module.exports.defaultRoutes = defaultRoutes
649+
module.exports.defaultHttpMethods = defaultHttpMethods
649650
module.exports.fastifyHttpProxy = fastifyHttpProxy

test/test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,29 @@ async function run () {
751751
t.assert.fail()
752752
})
753753

754+
test('settings of routes', async t => {
755+
const server = Fastify()
756+
server.register(proxy, {
757+
upstream: `http://localhost:${origin.server.address().port}`,
758+
routes: ['/a']
759+
})
760+
761+
await server.listen({ port: 0 })
762+
t.after(() => server.close())
763+
764+
const resultRoot = await got(`http://localhost:${server.server.address().port}/a`)
765+
t.assert.deepStrictEqual(resultRoot.statusCode, 200)
766+
767+
let errored = false
768+
try {
769+
await await got(`http://localhost:${server.server.address().port}/api2/a`)
770+
} catch (err) {
771+
t.assert.strictEqual(err.response.statusCode, 404)
772+
errored = true
773+
}
774+
t.assert.ok(errored)
775+
})
776+
754777
test('settings of method types', async t => {
755778
const server = Fastify()
756779
server.register(proxy, {
@@ -958,6 +981,34 @@ async function run () {
958981
t.assert.strictEqual(body, 'this is a')
959982
}
960983
})
984+
985+
test('preRewrite handler', async t => {
986+
const proxyServer = Fastify()
987+
988+
proxyServer.register(proxy, {
989+
upstream: `http://localhost:${origin.server.address().port}`,
990+
prefix: '/api',
991+
rewritePrefix: '/api2/',
992+
preRewrite (url, params, prefix) {
993+
t.assert.strictEqual(url, '/api/abc')
994+
t.assert.ok(typeof params, 'object')
995+
t.assert.strictEqual(params['*'], 'abc')
996+
t.assert.strictEqual(prefix, '/api')
997+
return url.replace('abc', 'a')
998+
}
999+
})
1000+
1001+
await proxyServer.listen({ port: 0 })
1002+
1003+
t.after(() => {
1004+
proxyServer.close()
1005+
})
1006+
1007+
const firstProxyPrefix = await got(
1008+
`http://localhost:${proxyServer.server.address().port}/api/abc`
1009+
)
1010+
t.assert.strictEqual(firstProxyPrefix.body, 'this is /api2/a')
1011+
})
9611012
}
9621013

9631014
run()

0 commit comments

Comments
 (0)