Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

handle non-Sapper responses when exporting #393

Merged
merged 1 commit into from
Aug 30, 2018
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
54 changes: 28 additions & 26 deletions src/api/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ async function execute(emitter: EventEmitter, opts: Opts) {
const port = await ports.find(3000);

const origin = `http://localhost:${port}`;
const root = new URL(opts.basepath || '', origin);
let basepath = opts.basepath || '/';
if (!basepath.endsWith('/')) basepath += '/';
let root = new URL(basepath, origin);

emitter.emit('info', {
message: `Crawling ${root.href}`
Expand All @@ -72,29 +74,15 @@ async function execute(emitter: EventEmitter, opts: Opts) {

const seen = new Set();
const saved = new Set();
const deferreds = new Map();

function get_deferred(pathname: string) {
pathname = pathname.replace(root.pathname, '');

if (!deferreds.has(pathname)) {
deferreds.set(pathname, new Deferred());
}

return deferreds.get(pathname);
}

proc.on('message', message => {
if (!message.__sapper__ || message.event !== 'file') return;

const pathname = new URL(message.url, origin).pathname;
function save(url: string, status: number, type: string, body: string) {
const pathname = new URL(url, origin).pathname;
let file = pathname.slice(1);
let { body } = message;

if (saved.has(file)) return;
saved.add(file);

const is_html = message.type === 'text/html';
const is_html = type === 'text/html';

if (is_html) {
file = file === '' ? 'index.html' : `${file}/index.html`;
Expand All @@ -104,12 +92,15 @@ async function execute(emitter: EventEmitter, opts: Opts) {
emitter.emit('file', <events.FileEvent>{
file,
size: body.length,
status: message.status
status
});

sander.writeFileSync(export_dir, file, body);
}

get_deferred(pathname).fulfil();
proc.on('message', message => {
if (!message.__sapper__ || message.event !== 'file') return;
save(message.url, message.status, message.type, message.body);
});

async function handle(url: URL) {
Expand All @@ -118,25 +109,27 @@ async function execute(emitter: EventEmitter, opts: Opts) {
if (seen.has(pathname)) return;
seen.add(pathname);

const deferred = get_deferred(pathname);

const timeout_deferred = new Deferred();
const timeout = setTimeout(() => {
timeout_deferred.reject(new Error(`Timed out waiting for ${url.href}`));
}, opts.timeout);

const r = await Promise.race([
fetch(url.href),
fetch(url.href, {
redirect: 'manual'
}),
timeout_deferred.promise
]);

clearTimeout(timeout); // prevent it hanging at the end

let type = r.headers.get('Content-Type');
let body = await r.text();

const range = ~~(r.status / 100);

if (range === 2) {
if (r.headers.get('Content-Type') === 'text/html') {
const body = await r.text();
if (type === 'text/html') {
const urls: URL[] = [];

const cleaned = clean_html(body);
Expand All @@ -162,7 +155,16 @@ async function execute(emitter: EventEmitter, opts: Opts) {
}
}

await deferred.promise;
if (range === 3) {
const location = r.headers.get('Location');

type = 'text/html';
body = `<script>window.location.href = "${location}"</script>`;

await handle(new URL(location, root));
}

save(pathname, r.status, type, body);
}

return ports.wait(port)
Expand Down
24 changes: 0 additions & 24 deletions src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,18 +414,6 @@ function get_page_handler(
res.setHeader('Location', location);
res.end();

if (process.send) {
process.send({
__sapper__: true,
event: 'file',
url: req.url,
method: req.method,
status: redirect.statusCode,
type: 'text/html',
body: `<script>window.location.href = "${location}"</script>`
});
}

return;
}

Expand Down Expand Up @@ -512,18 +500,6 @@ function get_page_handler(

res.statusCode = status;
res.end(body);

if (process.send) {
process.send({
__sapper__: true,
event: 'file',
url: req.url,
method: req.method,
status,
type: 'text/html',
body
});
}
}).catch(err => {
if (error) {
// we encountered an error while rendering the error page — oops
Expand Down
7 changes: 7 additions & 0 deletions test/app/app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ const middlewares = [
}),
];

app.get(`${BASEPATH}/non-sapper-redirect-from`, (req, res) => {
res.writeHead(301, {
Location: `${BASEPATH}/non-sapper-redirect-to`
});
res.end();
});

if (BASEPATH) {
app.use(BASEPATH, ...middlewares);
} else {
Expand Down
1 change: 1 addition & 0 deletions test/app/routes/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ <h1>Great success!</h1>
<a href='.'>home</a>
<a href='about'>about</a>
<a href='slow-preload'>slow preload</a>
<a href='non-sapper-redirect-from'>redirect</a>
<a href='redirect-from'>redirect</a>
<a href='redirect-root'>redirect (root)</a>
<a href='blog/nope'>broken link</a>
Expand Down
1 change: 1 addition & 0 deletions test/app/routes/non-sapper-redirect-to.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>redirected</h1>
7 changes: 5 additions & 2 deletions test/common/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ const fs = require('fs');
const path = require('path');
const assert = require('assert');
const Nightmare = require('nightmare');
const serve = require('serve-static');
const walkSync = require('walk-sync');
const fetch = require('node-fetch');
const rimraf = require('rimraf');
const ports = require('port-authority');

Expand Down Expand Up @@ -83,6 +81,11 @@ function testExport({ basepath = '' }) {
'about/index.html',
'slow-preload/index.html',

'redirect-from/index.html',
'redirect-to/index.html',
'non-sapper-redirect-from/index.html',
'non-sapper-redirect-to/index.html',

'blog/index.html',
'blog/a-very-long-post/index.html',
'blog/how-can-i-get-involved/index.html',
Expand Down