mirror of
https://github.com/withastro/astro.git
synced 2024-12-23 21:53:55 -05:00
404 when not using subpath for items in public in dev (#5328)
* 404 when not using subpath for items in public * Adding a changeset
This commit is contained in:
parent
48bde7018e
commit
bcd0f8f8c4
4 changed files with 69 additions and 3 deletions
7
.changeset/plenty-eyes-develop.md
Normal file
7
.changeset/plenty-eyes-develop.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
404 when not using subpath for items in public in dev
|
||||||
|
|
||||||
|
Previously if using a base like `base: '/subpath/` you could load things from the root, which would break in prod. Now you must include the subpath.
|
|
@ -5,6 +5,7 @@ import { LogOptions } from '../core/logger/core.js';
|
||||||
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
||||||
import { log404 } from './common.js';
|
import { log404 } from './common.js';
|
||||||
import { writeHtmlResponse } from './response.js';
|
import { writeHtmlResponse } from './response.js';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
export function baseMiddleware(
|
export function baseMiddleware(
|
||||||
settings: AstroSettings,
|
settings: AstroSettings,
|
||||||
|
@ -12,12 +13,13 @@ export function baseMiddleware(
|
||||||
): vite.Connect.NextHandleFunction {
|
): vite.Connect.NextHandleFunction {
|
||||||
const { config } = settings;
|
const { config } = settings;
|
||||||
const site = config.site ? new URL(config.base, config.site) : undefined;
|
const site = config.site ? new URL(config.base, config.site) : undefined;
|
||||||
const devRoot = site ? site.pathname : '/';
|
const devRoot = site ? site.pathname : new URL(config.base, 'http://localhost').pathname;
|
||||||
|
|
||||||
return function devBaseMiddleware(req, res, next) {
|
return function devBaseMiddleware(req, res, next) {
|
||||||
const url = req.url!;
|
const url = req.url!;
|
||||||
|
|
||||||
const pathname = decodeURI(new URL(url, 'http://vitejs.dev').pathname);
|
const pathname = decodeURI(new URL(url, 'http://localhost').pathname);
|
||||||
|
|
||||||
|
|
||||||
if (pathname.startsWith(devRoot)) {
|
if (pathname.startsWith(devRoot)) {
|
||||||
req.url = url.replace(devRoot, '/');
|
req.url = url.replace(devRoot, '/');
|
||||||
|
@ -41,6 +43,16 @@ export function baseMiddleware(
|
||||||
return writeHtmlResponse(res, 404, html);
|
return writeHtmlResponse(res, 404, html);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
// Check to see if it's in public and if so 404
|
||||||
|
const publicPath = new URL('.' + req.url, config.publicDir);
|
||||||
|
fs.stat(publicPath, (_err, stats) => {
|
||||||
|
if(stats) {
|
||||||
|
log404(logging, pathname);
|
||||||
|
const html = subpathNotUsedTemplate(devRoot, pathname);
|
||||||
|
return writeHtmlResponse(res, 404, html);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
1
packages/astro/test/fixtures/alias/public/test.txt
vendored
Normal file
1
packages/astro/test/fixtures/alias/public/test.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
this is a test
|
|
@ -157,4 +157,50 @@ describe('dev container', () => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('items in public/ are not available from root when using a base', async () => {
|
||||||
|
await runInContainer({
|
||||||
|
root,
|
||||||
|
userConfig: {
|
||||||
|
base: '/sub/'
|
||||||
|
}
|
||||||
|
}, async (container) => {
|
||||||
|
// First try the subpath
|
||||||
|
let r = createRequestAndResponse({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/sub/test.txt',
|
||||||
|
});
|
||||||
|
|
||||||
|
container.handle(r.req, r.res);
|
||||||
|
await r.done;
|
||||||
|
|
||||||
|
expect(r.res.statusCode).to.equal(200);
|
||||||
|
|
||||||
|
// Next try the root path
|
||||||
|
r = createRequestAndResponse({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/test.txt',
|
||||||
|
});
|
||||||
|
|
||||||
|
container.handle(r.req, r.res);
|
||||||
|
await r.done;
|
||||||
|
|
||||||
|
expect(r.res.statusCode).to.equal(404);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('items in public/ are available from root when not using a base', async () => {
|
||||||
|
await runInContainer({ root }, async (container) => {
|
||||||
|
// Try the root path
|
||||||
|
let r = createRequestAndResponse({
|
||||||
|
method: 'GET',
|
||||||
|
url: '/test.txt',
|
||||||
|
});
|
||||||
|
|
||||||
|
container.handle(r.req, r.res);
|
||||||
|
await r.done;
|
||||||
|
|
||||||
|
expect(r.res.statusCode).to.equal(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue