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

Commit c6af2dd

Browse files
authored
Merge pull request #393 from sveltejs/gh-392
handle non-Sapper responses when exporting
2 parents 1e22031 + 65d0172 commit c6af2dd

File tree

6 files changed

+42
-52
lines changed

6 files changed

+42
-52
lines changed

src/api/export.ts

+28-26
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ async function execute(emitter: EventEmitter, opts: Opts) {
5454
const port = await ports.find(3000);
5555

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

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

7375
const seen = new Set();
7476
const saved = new Set();
75-
const deferreds = new Map();
7677

77-
function get_deferred(pathname: string) {
78-
pathname = pathname.replace(root.pathname, '');
79-
80-
if (!deferreds.has(pathname)) {
81-
deferreds.set(pathname, new Deferred());
82-
}
83-
84-
return deferreds.get(pathname);
85-
}
86-
87-
proc.on('message', message => {
88-
if (!message.__sapper__ || message.event !== 'file') return;
89-
90-
const pathname = new URL(message.url, origin).pathname;
78+
function save(url: string, status: number, type: string, body: string) {
79+
const pathname = new URL(url, origin).pathname;
9180
let file = pathname.slice(1);
92-
let { body } = message;
9381

9482
if (saved.has(file)) return;
9583
saved.add(file);
9684

97-
const is_html = message.type === 'text/html';
85+
const is_html = type === 'text/html';
9886

9987
if (is_html) {
10088
file = file === '' ? 'index.html' : `${file}/index.html`;
@@ -104,12 +92,15 @@ async function execute(emitter: EventEmitter, opts: Opts) {
10492
emitter.emit('file', <events.FileEvent>{
10593
file,
10694
size: body.length,
107-
status: message.status
95+
status
10896
});
10997

11098
sander.writeFileSync(export_dir, file, body);
99+
}
111100

112-
get_deferred(pathname).fulfil();
101+
proc.on('message', message => {
102+
if (!message.__sapper__ || message.event !== 'file') return;
103+
save(message.url, message.status, message.type, message.body);
113104
});
114105

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

121-
const deferred = get_deferred(pathname);
122-
123112
const timeout_deferred = new Deferred();
124113
const timeout = setTimeout(() => {
125114
timeout_deferred.reject(new Error(`Timed out waiting for ${url.href}`));
126115
}, opts.timeout);
127116

128117
const r = await Promise.race([
129-
fetch(url.href),
118+
fetch(url.href, {
119+
redirect: 'manual'
120+
}),
130121
timeout_deferred.promise
131122
]);
132123

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

126+
let type = r.headers.get('Content-Type');
127+
let body = await r.text();
128+
135129
const range = ~~(r.status / 100);
136130

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

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

165-
await deferred.promise;
158+
if (range === 3) {
159+
const location = r.headers.get('Location');
160+
161+
type = 'text/html';
162+
body = `<script>window.location.href = "${location}"</script>`;
163+
164+
await handle(new URL(location, root));
165+
}
166+
167+
save(pathname, r.status, type, body);
166168
}
167169

168170
return ports.wait(port)

src/middleware.ts

-24
Original file line numberDiff line numberDiff line change
@@ -414,18 +414,6 @@ function get_page_handler(
414414
res.setHeader('Location', location);
415415
res.end();
416416

417-
if (process.send) {
418-
process.send({
419-
__sapper__: true,
420-
event: 'file',
421-
url: req.url,
422-
method: req.method,
423-
status: redirect.statusCode,
424-
type: 'text/html',
425-
body: `<script>window.location.href = "${location}"</script>`
426-
});
427-
}
428-
429417
return;
430418
}
431419

@@ -512,18 +500,6 @@ function get_page_handler(
512500

513501
res.statusCode = status;
514502
res.end(body);
515-
516-
if (process.send) {
517-
process.send({
518-
__sapper__: true,
519-
event: 'file',
520-
url: req.url,
521-
method: req.method,
522-
status,
523-
type: 'text/html',
524-
body
525-
});
526-
}
527503
}).catch(err => {
528504
if (error) {
529505
// we encountered an error while rendering the error page — oops

test/app/app/server.js

+7
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ const middlewares = [
108108
}),
109109
];
110110

111+
app.get(`${BASEPATH}/non-sapper-redirect-from`, (req, res) => {
112+
res.writeHead(301, {
113+
Location: `${BASEPATH}/non-sapper-redirect-to`
114+
});
115+
res.end();
116+
});
117+
111118
if (BASEPATH) {
112119
app.use(BASEPATH, ...middlewares);
113120
} else {

test/app/routes/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ <h1>Great success!</h1>
77
<a href='.'>home</a>
88
<a href='about'>about</a>
99
<a href='slow-preload'>slow preload</a>
10+
<a href='non-sapper-redirect-from'>redirect</a>
1011
<a href='redirect-from'>redirect</a>
1112
<a href='redirect-root'>redirect (root)</a>
1213
<a href='blog/nope'>broken link</a>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>redirected</h1>

test/common/test.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ const fs = require('fs');
22
const path = require('path');
33
const assert = require('assert');
44
const Nightmare = require('nightmare');
5-
const serve = require('serve-static');
65
const walkSync = require('walk-sync');
7-
const fetch = require('node-fetch');
86
const rimraf = require('rimraf');
97
const ports = require('port-authority');
108

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

84+
'redirect-from/index.html',
85+
'redirect-to/index.html',
86+
'non-sapper-redirect-from/index.html',
87+
'non-sapper-redirect-to/index.html',
88+
8689
'blog/index.html',
8790
'blog/a-very-long-post/index.html',
8891
'blog/how-can-i-get-involved/index.html',

0 commit comments

Comments
 (0)