summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2022-11-09 08:30:02 -0500
committerGravatar GitHub <noreply@github.com> 2022-11-09 08:30:02 -0500
commitbcd0f8f8c4c27d19296ec08d7bf7d8f5047d583e (patch)
tree3ecf5262010b685cb71fb498eb320702bd8e3acd
parent48bde7018e6b6a265a80e7aa282daf6e8ea607be (diff)
downloadastro-bcd0f8f8c4c27d19296ec08d7bf7d8f5047d583e.tar.gz
astro-bcd0f8f8c4c27d19296ec08d7bf7d8f5047d583e.tar.zst
astro-bcd0f8f8c4c27d19296ec08d7bf7d8f5047d583e.zip
404 when not using subpath for items in public in dev (#5328)
* 404 when not using subpath for items in public * Adding a changeset
-rw-r--r--.changeset/plenty-eyes-develop.md7
-rw-r--r--packages/astro/src/vite-plugin-astro-server/base.ts18
-rw-r--r--packages/astro/test/fixtures/alias/public/test.txt1
-rw-r--r--packages/astro/test/units/dev/dev.test.js46
4 files changed, 69 insertions, 3 deletions
diff --git a/.changeset/plenty-eyes-develop.md b/.changeset/plenty-eyes-develop.md
new file mode 100644
index 000000000..74073721b
--- /dev/null
+++ b/.changeset/plenty-eyes-develop.md
@@ -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.
diff --git a/packages/astro/src/vite-plugin-astro-server/base.ts b/packages/astro/src/vite-plugin-astro-server/base.ts
index 2618749db..dcab634b7 100644
--- a/packages/astro/src/vite-plugin-astro-server/base.ts
+++ b/packages/astro/src/vite-plugin-astro-server/base.ts
@@ -5,6 +5,7 @@ import { LogOptions } from '../core/logger/core.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import { log404 } from './common.js';
import { writeHtmlResponse } from './response.js';
+import * as fs from 'fs';
export function baseMiddleware(
settings: AstroSettings,
@@ -12,12 +13,13 @@ export function baseMiddleware(
): vite.Connect.NextHandleFunction {
const { config } = settings;
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) {
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)) {
req.url = url.replace(devRoot, '/');
@@ -41,6 +43,16 @@ export function baseMiddleware(
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();
+ }
+ });
};
}
diff --git a/packages/astro/test/fixtures/alias/public/test.txt b/packages/astro/test/fixtures/alias/public/test.txt
new file mode 100644
index 000000000..90bfcb510
--- /dev/null
+++ b/packages/astro/test/fixtures/alias/public/test.txt
@@ -0,0 +1 @@
+this is a test
diff --git a/packages/astro/test/units/dev/dev.test.js b/packages/astro/test/units/dev/dev.test.js
index 88fbaac45..062fcba23 100644
--- a/packages/astro/test/units/dev/dev.test.js
+++ b/packages/astro/test/units/dev/dev.test.js
@@ -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);
+ });
+ });
});