summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/wild-bees-sneeze.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/route.ts5
-rw-r--r--packages/astro/test/custom-404-implicit-rerouting.test.js57
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-1/astro.config.mjs1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-1/package.json8
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/404.astro4
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/index.astro1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-2/astro.config.mjs1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-2/package.json8
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/404.astro4
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/index.astro1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-3/astro.config.mjs1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-3/package.json8
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-3/src/middleware.js7
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/404.astro1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/index.astro1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-4/astro.config.mjs1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-4/package.json8
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-4/src/middleware.js6
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/404.astro1
-rw-r--r--packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/index.astro1
-rw-r--r--pnpm-lock.yaml24
22 files changed, 152 insertions, 2 deletions
diff --git a/.changeset/wild-bees-sneeze.md b/.changeset/wild-bees-sneeze.md
new file mode 100644
index 000000000..2f66136cf
--- /dev/null
+++ b/.changeset/wild-bees-sneeze.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixed an issue where a response with status code 404 led to an endless loop of implicit rerouting in dev mode.
diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts
index da2c4b948..50d8d34d7 100644
--- a/packages/astro/src/vite-plugin-astro-server/route.ts
+++ b/packages/astro/src/vite-plugin-astro-server/route.ts
@@ -220,6 +220,7 @@ export async function handleRoute({
let response = await pipeline.renderRoute(renderContext, mod);
if (response.status === 404 && has404Route(manifestData)) {
const fourOhFourRoute = await matchRoute('/404', manifestData, pipeline);
+ if (fourOhFourRoute?.route !== options.route)
return handleRoute({
...options,
matchedRoute: fourOhFourRoute,
@@ -342,6 +343,6 @@ function getStatus(matchedRoute?: MatchedRoute): 404 | 500 | undefined {
if (matchedRoute.route.route === '/500') return 500;
}
-function has404Route(manifest: ManifestData): RouteData | undefined {
- return manifest.routes.find((route) => route.route === '/404');
+function has404Route(manifest: ManifestData): boolean {
+ return manifest.routes.some((route) => route.route === '/404');
}
diff --git a/packages/astro/test/custom-404-implicit-rerouting.test.js b/packages/astro/test/custom-404-implicit-rerouting.test.js
new file mode 100644
index 000000000..4a5276c86
--- /dev/null
+++ b/packages/astro/test/custom-404-implicit-rerouting.test.js
@@ -0,0 +1,57 @@
+import { expect } from 'chai';
+import { loadFixture } from './test-utils.js';
+
+for (const caseNumber of [ 1, 2, 3, 4 ]) {
+ describe(`Custom 404 with implicit rerouting - Case #${caseNumber}`, () => {
+ /** @type Awaited<ReturnType<typeof loadFixture>> */
+ let fixture;
+ /** @type Awaited<ReturnType<typeof fixture['startDevServer']>> */
+ let devServer
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: `./fixtures/custom-404-loop-case-${caseNumber}/`,
+ site: 'http://example.com'
+ });
+
+ devServer = await fixture.startDevServer();
+ });
+
+ // sanity check
+ it('dev server handles normal requests', async () => {
+ const resPromise = fixture.fetch('/');
+ const result = await withTimeout(resPromise, 1000);
+ expect(result).to.not.equal(timeout);
+ expect(result.status).to.equal(200);
+ });
+
+ it('dev server stays responsive', async () => {
+ const resPromise = fixture.fetch('/alvsibdlvjks');
+ const result = await withTimeout(resPromise, 1000);
+ expect(result).to.not.equal(timeout);
+ expect(result.status).to.equal(404);
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+ });
+}
+
+
+/***** UTILITY FUNCTIONS *****/
+
+const timeout = Symbol("timeout")
+
+/** @template Res */
+function withTimeout(
+ /** @type Promise<Res> */
+ responsePromise,
+ /** @type number */
+ timeLimit
+) {
+ /** @type Promise<typeof timeout> */
+ const timeoutPromise = new Promise(resolve => setTimeout(() => resolve(timeout), timeLimit))
+
+ return Promise.race([ responsePromise, timeoutPromise ]);
+} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-1/astro.config.mjs b/packages/astro/test/fixtures/custom-404-loop-case-1/astro.config.mjs
new file mode 100644
index 000000000..56004c9f9
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-1/astro.config.mjs
@@ -0,0 +1 @@
+export default {} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-1/package.json b/packages/astro/test/fixtures/custom-404-loop-case-1/package.json
new file mode 100644
index 000000000..cbc4f22ed
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-1/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/custom-404-loop-case-1",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/404.astro b/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/404.astro
new file mode 100644
index 000000000..ff217453d
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/404.astro
@@ -0,0 +1,4 @@
+---
+Astro.response.status = 404
+---
+<p>four oh four route</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/index.astro b/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/index.astro
new file mode 100644
index 000000000..a65c81fdb
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-1/src/pages/index.astro
@@ -0,0 +1 @@
+<p>all good here... or is it?</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-2/astro.config.mjs b/packages/astro/test/fixtures/custom-404-loop-case-2/astro.config.mjs
new file mode 100644
index 000000000..56004c9f9
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-2/astro.config.mjs
@@ -0,0 +1 @@
+export default {} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-2/package.json b/packages/astro/test/fixtures/custom-404-loop-case-2/package.json
new file mode 100644
index 000000000..2c5d3be55
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-2/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/custom-404-loop-case-2",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/404.astro b/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/404.astro
new file mode 100644
index 000000000..0c079adca
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/404.astro
@@ -0,0 +1,4 @@
+---
+return new Response(null, { status: 404 })
+---
+<p>four oh four route</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/index.astro b/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/index.astro
new file mode 100644
index 000000000..a65c81fdb
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-2/src/pages/index.astro
@@ -0,0 +1 @@
+<p>all good here... or is it?</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-3/astro.config.mjs b/packages/astro/test/fixtures/custom-404-loop-case-3/astro.config.mjs
new file mode 100644
index 000000000..56004c9f9
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-3/astro.config.mjs
@@ -0,0 +1 @@
+export default {} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-3/package.json b/packages/astro/test/fixtures/custom-404-loop-case-3/package.json
new file mode 100644
index 000000000..51b90b3cb
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-3/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/custom-404-loop-case-3",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-3/src/middleware.js b/packages/astro/test/fixtures/custom-404-loop-case-3/src/middleware.js
new file mode 100644
index 000000000..992ca1de8
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-3/src/middleware.js
@@ -0,0 +1,7 @@
+export async function onRequest(ctx, next) {
+ if (ctx.url.pathname !== '/') {
+ const response = await next()
+ return new Response(response.body, { ...response, status: 404 })
+ }
+ return next();
+} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/404.astro b/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/404.astro
new file mode 100644
index 000000000..af3c5ef0a
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/404.astro
@@ -0,0 +1 @@
+<p>four oh four route</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/index.astro b/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/index.astro
new file mode 100644
index 000000000..a65c81fdb
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-3/src/pages/index.astro
@@ -0,0 +1 @@
+<p>all good here... or is it?</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-4/astro.config.mjs b/packages/astro/test/fixtures/custom-404-loop-case-4/astro.config.mjs
new file mode 100644
index 000000000..56004c9f9
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-4/astro.config.mjs
@@ -0,0 +1 @@
+export default {} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-4/package.json b/packages/astro/test/fixtures/custom-404-loop-case-4/package.json
new file mode 100644
index 000000000..0fb69f513
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-4/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@test/custom-404-loop-case-4",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-4/src/middleware.js b/packages/astro/test/fixtures/custom-404-loop-case-4/src/middleware.js
new file mode 100644
index 000000000..6ab0cac69
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-4/src/middleware.js
@@ -0,0 +1,6 @@
+export function onRequest(ctx, next) {
+ if (ctx.url.pathname !== '/') {
+ return new Response(null, { status: 404 });
+ }
+ return next();
+} \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/404.astro b/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/404.astro
new file mode 100644
index 000000000..af3c5ef0a
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/404.astro
@@ -0,0 +1 @@
+<p>four oh four route</p> \ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/index.astro b/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/index.astro
new file mode 100644
index 000000000..a65c81fdb
--- /dev/null
+++ b/packages/astro/test/fixtures/custom-404-loop-case-4/src/pages/index.astro
@@ -0,0 +1 @@
+<p>all good here... or is it?</p> \ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f8cdb77b2..64c4f0d2e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -2561,6 +2561,30 @@ importers:
specifier: workspace:*
version: link:../../..
+ packages/astro/test/fixtures/custom-404-loop-case-1:
+ dependencies:
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
+ packages/astro/test/fixtures/custom-404-loop-case-2:
+ dependencies:
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
+ packages/astro/test/fixtures/custom-404-loop-case-3:
+ dependencies:
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
+ packages/astro/test/fixtures/custom-404-loop-case-4:
+ dependencies:
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
packages/astro/test/fixtures/custom-404-md:
dependencies:
astro: