From 32714f0824577593ad7a342dde9a1140709f6003 Mon Sep 17 00:00:00 2001 From: Kunal Kundu <51631122+tinfoil-knight@users.noreply.github.com> Date: Fri, 4 Feb 2022 20:11:19 +0530 Subject: [PATCH] fix: external redirects not being matched correctly closes #3770 (#4109) * test: add failing test to reproduce issue with 301 redirects * fix: external redirects not being matched correctly Co-authored-by: Erez Rokah Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- src/utils/proxy.js | 8 ++++---- tests/integration/0.command.dev.test.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/utils/proxy.js b/src/utils/proxy.js index 972c9bb4663..ad82abc814e 100644 --- a/src/utils/proxy.js +++ b/src/utils/proxy.js @@ -213,6 +213,10 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) { const destURL = stripOrigin(dest) + if (isExternal(match)) { + return proxyToExternalUrl({ req, res, dest, destURL }) + } + if (isRedirect(match)) { res.writeHead(match.status, { Location: destURL, @@ -222,10 +226,6 @@ const serveRedirect = async function ({ match, options, proxy, req, res }) { return } - if (isExternal(match)) { - return proxyToExternalUrl({ req, res, dest, destURL }) - } - const ct = req.headers['content-type'] ? contentType.parse(req).type : '' if ( req.method === 'POST' && diff --git a/tests/integration/0.command.dev.test.js b/tests/integration/0.command.dev.test.js index 37238b4dee0..adfd0c4ac57 100644 --- a/tests/integration/0.command.dev.test.js +++ b/tests/integration/0.command.dev.test.js @@ -199,6 +199,25 @@ testMatrix.forEach(({ args }) => { }) }) + test(testName('should follow 301 redirect to an external server', args), async (t) => { + await withSiteBuilder('site-redirects-file-to-external-301', async (builder) => { + const externalServer = startExternalServer() + const { port } = externalServer.address() + builder.withRedirectsFile({ + redirects: [{ from: '/api/*', to: `http://localhost:${port}/:splat`, status: 301 }], + }) + + await builder.buildAsync() + + await withDevServer({ cwd: builder.directory, args }, async (server) => { + const response = await got(`${server.url}/api/ping`).json() + t.deepEqual(response, { body: {}, method: 'GET', url: '/ping' }) + }) + + externalServer.close() + }) + }) + test(testName('should redirect POST request if content-type is missing', args), async (t) => { await withSiteBuilder('site-with-post-no-content-type', async (builder) => { builder.withNetlifyToml({