From e69cb3639adc97d61fa878f454f22693093c98f6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 27 Oct 2018 12:14:28 -0400 Subject: [PATCH] redirect to external URLs - closes #490 --- .../src/server/middleware/get_page_handler.ts | 4 +- test/apps/AppRunner.ts | 14 ++++++ test/apps/redirects/src/routes/index.html | 3 +- .../src/routes/redirect-to-external.html | 9 ++++ test/apps/redirects/test.ts | 44 ++++++++++++++++--- 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 test/apps/redirects/src/routes/redirect-to-external.html diff --git a/templates/src/server/middleware/get_page_handler.ts b/templates/src/server/middleware/get_page_handler.ts index c2049f2..78eb559 100644 --- a/templates/src/server/middleware/get_page_handler.ts +++ b/templates/src/server/middleware/get_page_handler.ts @@ -3,7 +3,7 @@ import * as path from 'path'; import cookie from 'cookie'; import devalue from 'devalue'; import fetch from 'node-fetch'; -import { URL } from 'url'; +import { URL, resolve } from 'url'; import { build_dir, dev, src_dir, IGNORE } from '../placeholders'; import { Manifest, Page, Props, Req, Res, Store } from './types'; @@ -160,7 +160,7 @@ export function get_page_handler( try { if (redirect) { - const location = `${req.baseUrl}/${redirect.location}`; + const location = resolve(req.baseUrl || '/', redirect.location); res.statusCode = redirect.statusCode; res.setHeader('Location', location); diff --git a/test/apps/AppRunner.ts b/test/apps/AppRunner.ts index 077a3b7..0965329 100644 --- a/test/apps/AppRunner.ts +++ b/test/apps/AppRunner.ts @@ -50,6 +50,20 @@ export class AppRunner { } }); + await this.page.setRequestInterception(true); + + this.page.on('request', interceptedRequest => { + if (/example\.com/.test(interceptedRequest.url())) { + interceptedRequest.respond({ + status: 200, + contentType: 'text/html', + body: `

external

` + }); + } else { + interceptedRequest.continue(); + } + }); + return { page: this.page, base: `http://localhost:${this.port}`, diff --git a/test/apps/redirects/src/routes/index.html b/test/apps/redirects/src/routes/index.html index 6a94654..804a3dc 100644 --- a/test/apps/redirects/src/routes/index.html +++ b/test/apps/redirects/src/routes/index.html @@ -1,4 +1,5 @@

root

redirect from -redirect to root \ No newline at end of file +redirect to root +redirect to external \ No newline at end of file diff --git a/test/apps/redirects/src/routes/redirect-to-external.html b/test/apps/redirects/src/routes/redirect-to-external.html new file mode 100644 index 0000000..fec2fee --- /dev/null +++ b/test/apps/redirects/src/routes/redirect-to-external.html @@ -0,0 +1,9 @@ +

unredirected

+ + \ No newline at end of file diff --git a/test/apps/redirects/test.ts b/test/apps/redirects/test.ts index 8054924..719a92c 100644 --- a/test/apps/redirects/test.ts +++ b/test/apps/redirects/test.ts @@ -14,13 +14,14 @@ describe('redirects', function() { // helpers let start: () => Promise; let prefetchRoutes: () => Promise; + let title: () => Promise; // hooks before(async () => { await build({ cwd: __dirname }); runner = new AppRunner(__dirname, '__sapper__/build/server/server.js'); - ({ base, page, start, prefetchRoutes } = await runner.start()); + ({ base, page, start, prefetchRoutes, title } = await runner.start()); }); after(() => runner.end()); @@ -34,7 +35,7 @@ describe('redirects', function() { ); assert.equal( - await page.$eval('h1', node => node.textContent), + await title(), 'redirected' ); }); @@ -53,7 +54,7 @@ describe('redirects', function() { ); assert.equal( - await page.$eval('h1', node => node.textContent), + await title(), 'redirected' ); }); @@ -67,7 +68,7 @@ describe('redirects', function() { ); assert.equal( - await page.$eval('h1', node => node.textContent), + await title(), 'root' ); }); @@ -86,8 +87,41 @@ describe('redirects', function() { ); assert.equal( - await page.$eval('h1', node => node.textContent), + await title(), 'root' ); }); + + it('redirects to external URL on server', async () => { + await page.goto(`${base}/redirect-to-external`); + + assert.equal( + page.url(), + `https://example.com/` + ); + + assert.equal( + await title(), + 'external' + ); + }); + + it('redirects to external URL in client', async () => { + await page.goto(base); + await start(); + await prefetchRoutes(); + + await page.click('[href="redirect-to-external"]'); + await wait(50); + + assert.equal( + page.url(), + `https://example.com/` + ); + + assert.equal( + await title(), + 'external' + ); + }); }); \ No newline at end of file