Skip to content

Commit 74fe6c9

Browse files
authored
added support for dynamical upstream configuration (#178)
* added support for dynamical upstream confuguration replyOptions.getUpstream must be specified for this * optional chaining eliminated to support node.js 10 tests added * code refactoring
1 parent f47c862 commit 74fe6c9

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ function generateRewritePrefix (prefix, opts) {
117117
return ''
118118
}
119119

120-
let rewritePrefix = opts.rewritePrefix || new URL(opts.upstream).pathname
120+
let rewritePrefix = opts.rewritePrefix || (opts.upstream ? new URL(opts.upstream).pathname : '/')
121121

122122
if (!prefix.endsWith('/') && rewritePrefix.endsWith('/')) {
123123
rewritePrefix = rewritePrefix.slice(0, -1)
@@ -127,7 +127,7 @@ function generateRewritePrefix (prefix, opts) {
127127
}
128128

129129
async function httpProxy (fastify, opts) {
130-
if (!opts.upstream) {
130+
if (!opts.upstream && !(opts.upstream === '' && opts.replyOptions && typeof opts.replyOptions.getUpstream === 'function')) {
131131
throw new Error('upstream must be specified')
132132
}
133133

test/test.js

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,31 @@ async function run () {
6262
t.equal(resultA.body, 'this is a')
6363
})
6464

65+
test('dynamic upstream for basic proxy', async t => {
66+
const server = Fastify()
67+
server.register(proxy, {
68+
upstream: '',
69+
replyOptions: {
70+
getUpstream: function (original, base) {
71+
return `http://localhost:${origin.server.address().port}`
72+
}
73+
}
74+
})
75+
76+
await server.listen(0)
77+
t.teardown(server.close.bind(server))
78+
79+
const resultRoot = await got(
80+
`http://localhost:${server.server.address().port}`
81+
)
82+
t.equal(resultRoot.body, 'this is root')
83+
84+
const resultA = await got(
85+
`http://localhost:${server.server.address().port}/a`
86+
)
87+
t.equal(resultA.body, 'this is a')
88+
})
89+
6590
test('redirects passthrough', async t => {
6691
const server = Fastify()
6792
server.register(proxy, {
@@ -83,6 +108,32 @@ async function run () {
83108
t.equal(statusCode, 302)
84109
})
85110

111+
test('dynamic upstream for redirects passthrough', async t => {
112+
const server = Fastify()
113+
server.register(proxy, {
114+
upstream: '',
115+
replyOptions: {
116+
getUpstream: function (original, base) {
117+
return `http://localhost:${origin.server.address().port}`
118+
}
119+
}
120+
})
121+
122+
await server.listen(0)
123+
t.teardown(server.close.bind(server))
124+
125+
const {
126+
headers: { location },
127+
statusCode
128+
} = await got(
129+
`http://localhost:${server.server.address().port}/redirect`, {
130+
followRedirect: false
131+
}
132+
)
133+
t.equal(location, 'https://fastify.io')
134+
t.equal(statusCode, 302)
135+
})
136+
86137
test('no upstream will throw', async t => {
87138
const server = Fastify()
88139
server.register(proxy)
@@ -121,6 +172,37 @@ async function run () {
121172
t.equal(resultA.body, 'this is a')
122173
})
123174

175+
test('dynamic upstream for prefixed proxy', async t => {
176+
const server = Fastify()
177+
server.register(proxy, {
178+
upstream: '',
179+
prefix: '/my-prefix',
180+
replyOptions: {
181+
getUpstream: function (original, base) {
182+
return `http://localhost:${origin.server.address().port}`
183+
}
184+
}
185+
})
186+
187+
await server.listen(0)
188+
t.teardown(server.close.bind(server))
189+
190+
const resultRoot = await got(
191+
`http://localhost:${server.server.address().port}/my-prefix/`
192+
)
193+
t.equal(resultRoot.body, 'this is root')
194+
195+
const withoutSlash = await got(
196+
`http://localhost:${server.server.address().port}/my-prefix`
197+
)
198+
t.equal(withoutSlash.body, 'this is root')
199+
200+
const resultA = await got(
201+
`http://localhost:${server.server.address().port}/my-prefix/a`
202+
)
203+
t.equal(resultA.body, 'this is a')
204+
})
205+
124206
test('posting stuff', async t => {
125207
const server = Fastify()
126208
server.register(proxy, {
@@ -141,6 +223,31 @@ async function run () {
141223
t.same(resultRoot.body, { something: 'posted' })
142224
})
143225

226+
test('dynamic upstream for posting stuff', async t => {
227+
const server = Fastify()
228+
server.register(proxy, {
229+
upstream: '',
230+
replyOptions: {
231+
getUpstream: function (original, base) {
232+
return `http://localhost:${origin.server.address().port}`
233+
}
234+
}
235+
})
236+
237+
await server.listen(0)
238+
t.teardown(server.close.bind(server))
239+
240+
const resultRoot = await got(
241+
`http://localhost:${server.server.address().port}/this-has-data`,
242+
{
243+
method: 'POST',
244+
json: { hello: 'world' },
245+
responseType: 'json'
246+
}
247+
)
248+
t.same(resultRoot.body, { something: 'posted' })
249+
})
250+
144251
test('skip proxying the incoming payload', async t => {
145252
const server = Fastify()
146253
server.register(proxy, {

0 commit comments

Comments
 (0)