Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for dynamical upstream configuration #178

Merged
merged 3 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function generateRewritePrefix (prefix, opts) {
return ''
}

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

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

async function httpProxy (fastify, opts) {
if (!opts.upstream) {
if (!opts.upstream && !(opts.upstream === '' && opts.replyOptions && typeof opts.replyOptions.getUpstream === 'function')) {
throw new Error('upstream must be specified')
}

Expand Down
107 changes: 107 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,31 @@ async function run () {
t.equal(resultA.body, 'this is a')
})

test('dynamic upstream for basic proxy', async t => {
const server = Fastify()
server.register(proxy, {
upstream: '',
replyOptions: {
getUpstream: function (original, base) {
return `http://localhost:${origin.server.address().port}`
}
}
})

await server.listen(0)
t.teardown(server.close.bind(server))

const resultRoot = await got(
`http://localhost:${server.server.address().port}`
)
t.equal(resultRoot.body, 'this is root')

const resultA = await got(
`http://localhost:${server.server.address().port}/a`
)
t.equal(resultA.body, 'this is a')
})

test('redirects passthrough', async t => {
const server = Fastify()
server.register(proxy, {
Expand All @@ -83,6 +108,32 @@ async function run () {
t.equal(statusCode, 302)
})

test('dynamic upstream for redirects passthrough', async t => {
const server = Fastify()
server.register(proxy, {
upstream: '',
replyOptions: {
getUpstream: function (original, base) {
return `http://localhost:${origin.server.address().port}`
}
}
})

await server.listen(0)
t.teardown(server.close.bind(server))

const {
headers: { location },
statusCode
} = await got(
`http://localhost:${server.server.address().port}/redirect`, {
followRedirect: false
}
)
t.equal(location, 'https://fastify.io')
t.equal(statusCode, 302)
})

test('no upstream will throw', async t => {
const server = Fastify()
server.register(proxy)
Expand Down Expand Up @@ -121,6 +172,37 @@ async function run () {
t.equal(resultA.body, 'this is a')
})

test('dynamic upstream for prefixed proxy', async t => {
const server = Fastify()
server.register(proxy, {
upstream: '',
prefix: '/my-prefix',
replyOptions: {
getUpstream: function (original, base) {
return `http://localhost:${origin.server.address().port}`
}
}
})

await server.listen(0)
t.teardown(server.close.bind(server))

const resultRoot = await got(
`http://localhost:${server.server.address().port}/my-prefix/`
)
t.equal(resultRoot.body, 'this is root')

const withoutSlash = await got(
`http://localhost:${server.server.address().port}/my-prefix`
)
t.equal(withoutSlash.body, 'this is root')

const resultA = await got(
`http://localhost:${server.server.address().port}/my-prefix/a`
)
t.equal(resultA.body, 'this is a')
})

test('posting stuff', async t => {
const server = Fastify()
server.register(proxy, {
Expand All @@ -141,6 +223,31 @@ async function run () {
t.same(resultRoot.body, { something: 'posted' })
})

test('dynamic upstream for posting stuff', async t => {
const server = Fastify()
server.register(proxy, {
upstream: '',
replyOptions: {
getUpstream: function (original, base) {
return `http://localhost:${origin.server.address().port}`
}
}
})

await server.listen(0)
t.teardown(server.close.bind(server))

const resultRoot = await got(
`http://localhost:${server.server.address().port}/this-has-data`,
{
method: 'POST',
json: { hello: 'world' },
responseType: 'json'
}
)
t.same(resultRoot.body, { something: 'posted' })
})

test('skip proxying the incoming payload', async t => {
const server = Fastify()
server.register(proxy, {
Expand Down