diff --git a/example.js b/example.js index bbdf491..9ef55b8 100644 --- a/example.js +++ b/example.js @@ -5,10 +5,15 @@ const proxy = require('.') async function startOrigin () { const origin = Fastify() + origin.get('/', async (request, reply) => { return 'this is root' }) + origin.get('/redirect', async (request, reply) => { + return reply.redirect(302, 'https://fastify.io') + }) + origin.get('/a', async (request, reply) => { return 'this is a' }) diff --git a/index.js b/index.js index f35cfbe..24b1659 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ 'use strict' - const From = require('fastify-reply-from') const WebSocket = require('ws') const httpMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS'] +const urlPattern = /^https?:\/\// function liftErrorCode (code) { if (typeof code !== 'number') { @@ -31,6 +31,10 @@ function waitConnection (socket, write) { } } +function isExternalUrl (url = '') { + return urlPattern.test(url) +}; + function proxyWebSockets (source, target) { function close (code, reason) { closeWebSocket(source, code, reason) @@ -125,7 +129,7 @@ async function httpProxy (fastify, opts) { function rewriteHeaders (headers) { const location = headers.location - if (location) { + if (location && !isExternalUrl(location)) { headers.location = location.replace(rewritePrefix, fastify.prefix) } if (oldRewriteHeaders) { diff --git a/test/test.js b/test/test.js index 378af8b..5c3549e 100644 --- a/test/test.js +++ b/test/test.js @@ -17,6 +17,10 @@ async function run () { return 'this is a' }) + origin.get('/redirect', async (request, reply) => { + return reply.redirect(302, 'https://fastify.io') + }) + origin.post('/this-has-data', async (request, reply) => { if (request.body.hello === 'world') { reply.header('location', '/something') @@ -58,6 +62,27 @@ async function run () { t.equal(resultA.body, 'this is a') }) + test('redirects passthrough', async t => { + const server = Fastify() + server.register(proxy, { + upstream: `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)