0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-27 22:19:04 -05:00

Replace send with sirv (#2713)

* remove send

* Create thick-ravens-chew.md

* I feel like I'm going to screw something up

* working finally!

* rewrite req.url

* Add tiny bit of doc

* Update .gitignore

Co-authored-by: Evan Boehs <evan@boehs.org>
This commit is contained in:
Nate Moore 2022-03-03 15:10:02 -06:00 committed by Nate Moore
parent fbf2431f51
commit 556e51eecc
4 changed files with 27 additions and 67 deletions

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Replace `send` dependency with `sirv`

View file

View file

@ -95,7 +95,7 @@
"resolve": "^1.20.0", "resolve": "^1.20.0",
"rollup": "^2.64.0", "rollup": "^2.64.0",
"semver": "^7.3.5", "semver": "^7.3.5",
"send": "^0.17.1", "sirv": "^2.0.2",
"serialize-javascript": "^6.0.0", "serialize-javascript": "^6.0.0",
"shiki": "^0.10.0", "shiki": "^0.10.0",
"shorthash": "^0.0.2", "shorthash": "^0.0.2",
@ -125,7 +125,6 @@
"@types/parse5": "^6.0.3", "@types/parse5": "^6.0.3",
"@types/resolve": "^1.20.1", "@types/resolve": "^1.20.1",
"@types/rimraf": "^3.0.2", "@types/rimraf": "^3.0.2",
"@types/send": "^0.17.1",
"@types/yargs-parser": "^20.2.1", "@types/yargs-parser": "^20.2.1",
"astro-scripts": "workspace:*", "astro-scripts": "workspace:*",
"chai": "^4.3.4", "chai": "^4.3.4",

View file

@ -1,17 +1,14 @@
import type { AstroConfig } from '../../@types/astro'; import type { AstroConfig } from '../../@types/astro';
import type { LogOptions } from '../logger'; import type { LogOptions } from '../logger';
import type { Stats } from 'fs';
import type { AddressInfo } from 'net'; import type { AddressInfo } from 'net';
import http from 'http'; import http from 'http';
import sirv from 'sirv';
import { performance } from 'perf_hooks'; import { performance } from 'perf_hooks';
import send from 'send';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import fs from 'fs';
import * as msg from '../messages.js'; import * as msg from '../messages.js';
import { error, info } from '../logger.js'; import { error, info } from '../logger.js';
import { subpathNotUsedTemplate, notFoundTemplate, default as template } from '../../template/4xx.js'; import { subpathNotUsedTemplate, notFoundTemplate } from '../../template/4xx.js';
import { appendForwardSlash, trimSlashes } from '../path.js';
import { getLocalAddress } from '../dev/util.js'; import { getLocalAddress } from '../dev/util.js';
interface PreviewOptions { interface PreviewOptions {
@ -28,22 +25,8 @@ export interface PreviewServer {
/** The primary dev action */ /** The primary dev action */
export default async function preview(config: AstroConfig, { logging }: PreviewOptions): Promise<PreviewServer> { export default async function preview(config: AstroConfig, { logging }: PreviewOptions): Promise<PreviewServer> {
const startServerTime = performance.now(); const startServerTime = performance.now();
const pageUrlFormat = config.buildOptions.pageUrlFormat;
const trailingSlash = config.devOptions.trailingSlash;
const forceTrailingSlash = trailingSlash === 'always';
const blockTrailingSlash = trailingSlash === 'never';
/** Default file served from a directory. */
const defaultFile = 'index.html';
const defaultOrigin = 'http://localhost'; const defaultOrigin = 'http://localhost';
const trailingSlash = config.devOptions.trailingSlash
const sendOptions = {
extensions: pageUrlFormat === 'file' ? ['html'] : false,
index: false,
root: fileURLToPath(config.dist),
};
/** Base request URL. */ /** Base request URL. */
let baseURL = new URL(config.buildOptions.site || '/', defaultOrigin); let baseURL = new URL(config.buildOptions.site || '/', defaultOrigin);
@ -64,55 +47,28 @@ export default async function preview(config: AstroConfig, { logging }: PreviewO
const isRoot = pathname === '/'; const isRoot = pathname === '/';
const hasTrailingSlash = isRoot || pathname.endsWith('/'); const hasTrailingSlash = isRoot || pathname.endsWith('/');
let tryTrailingSlash = true; function err(message: string) {
let tryHtmlExtension = true;
let url: URL;
const onErr = (message: string) => {
res.statusCode = 404; res.statusCode = 404;
res.end(notFoundTemplate(pathname, message)); res.end(notFoundTemplate(pathname, message));
}; };
const onStat = (err: NodeJS.ErrnoException | null, stat: Stats) => { switch(true) {
switch (true) { case hasTrailingSlash && trailingSlash == 'never' && !isRoot:
// retry nonexistent paths without an html extension err('Prohibited trailing slash');
case err && tryHtmlExtension && hasTrailingSlash && !blockTrailingSlash: break;
case err && tryHtmlExtension && !hasTrailingSlash && !forceTrailingSlash && !pathname.endsWith('.html'): case !hasTrailingSlash && trailingSlash == 'always' && !isRoot:
tryHtmlExtension = false; err('Required trailing slash');
return fs.stat((url = new URL(url.pathname + '.html', url)), onStat); break;
default: {
// 404 on nonexistent paths (that are yet handled) // HACK: rewrite req.url so that sirv finds the file
case err !== null: req.url = '/' + req.url?.replace(baseURL.pathname,'')
return onErr('Path not found'); sirv(fileURLToPath(config.dist), {
maxAge: 0,
// 404 on directories when a trailing slash is present but blocked onNoMatch: () => {
case stat.isDirectory() && hasTrailingSlash && blockTrailingSlash && !isRoot: err('Path not found')
return onErr('Prohibited trailing slash'); }
})(req,res)
// 404 on directories when a trailing slash is missing but forced }}
case stat.isDirectory() && !hasTrailingSlash && forceTrailingSlash && !isRoot:
return onErr('Required trailing slash');
// retry on directories when a default file is missing but allowed (that are yet handled)
case stat.isDirectory() && tryTrailingSlash:
tryTrailingSlash = false;
return fs.stat((url = new URL(url.pathname + (url.pathname.endsWith('/') ? defaultFile : '/' + defaultFile), url)), onStat);
// 404 on existent directories (that are yet handled)
case stat.isDirectory():
return onErr('Path not found');
// handle existent paths
default:
send(req, fileURLToPath(url), {
extensions: false,
index: false,
}).pipe(res);
}
};
fs.stat((url = new URL(trimSlashes(pathname), config.dist)), onStat);
}); });
let { hostname, port } = config.devOptions; let { hostname, port } = config.devOptions;