Skip to content

Commit

Permalink
fix: handle requests for double slash in dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ascorbic committed Dec 13, 2024
1 parent 799c867 commit 529b6e5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/twenty-cherries-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes a bug that caused the dev server to return an error if requesting "//"
25 changes: 25 additions & 0 deletions packages/astro/src/core/routing/manifest/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ function detectRouteCollision(a: RouteData, b: RouteData, _config: AstroConfig,
// Fallbacks are always added below other routes exactly to avoid collisions.
return;
}
// The double-slash redirect will never collide with any other route.
if (a.route === '//' || b.route === '//') {
return;
}

if (
a.route === b.route &&
Expand Down Expand Up @@ -502,6 +506,27 @@ export async function createRouteManifest(
}

const redirectRoutes = createRedirectRoutes(params, routeMap, logger);
if (dev) {
// Add a redirect for `//` to `/`. We only do this in dev because different platforms
// vary a lot in how or whether they handle this sort of redirect, so we leave it to the adapter
redirectRoutes.push({
type: 'redirect',
isIndex: false,
route: '//',
pattern: /^\/+$/,
segments: [],
params: [],
component: '/',
generate: () => '//',
pathname: '//',
prerender: false,
redirect: '/',
redirectRoute: routeMap.get('/'),
fallbackRoutes: [],
distURL: [],
origin: 'project',
});
}

// we remove the file based routes that were deemed redirects
const filteredFiledBasedRoutes = fileBasedRoutes.filter((fileBasedRoute) => {
Expand Down
4 changes: 3 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import type { Logger } from '../core/logger/core.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import { writeHtmlResponse } from './response.js';

const justSlashes = /^\/{2,}$/;

export function baseMiddleware(
settings: AstroSettings,
logger: Logger,
Expand All @@ -24,7 +26,7 @@ export function baseMiddleware(

let pathname: string;
try {
pathname = decodeURI(new URL(url, 'http://localhost').pathname);
pathname = justSlashes.test(url) ? '//' : decodeURI(new URL(url, 'http://localhost').pathname);
} catch (e) {
/* malform uri */
return next(e);
Expand Down
13 changes: 13 additions & 0 deletions packages/astro/test/dev-routing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ describe('Development Routing', () => {
assert.equal(response.status, 200);
});

it('redirects when loading double slash', async () => {
const response = await fixture.fetch('//', { redirect: 'manual' });
assert.equal(response.status, 301);
assert.equal(response.headers.get('Location'), '/');
});

it('redirects when loading multiple slashes', async () => {
const response = await fixture.fetch('/////', { redirect: 'manual' });
assert.equal(response.status, 301);
assert.equal(response.headers.get('Location'), '/');
});


it('404 when loading invalid dynamic route', async () => {
const response = await fixture.fetch('/2');
assert.equal(response.status, 404);
Expand Down

0 comments on commit 529b6e5

Please sign in to comment.