From c23a529df430c29d72f95f22ee04acf338227e56 Mon Sep 17 00:00:00 2001 From: Alber Tenez Date: Fri, 13 Oct 2023 19:13:24 +0200 Subject: [PATCH 1/2] TrailingSlash using rewrite for a fetch call results on infinite loop Fixes: #279 --- .../open-next/src/adapters/routing/matcher.ts | 6 ++++-- packages/tests-e2e/README.md | 4 ++-- .../tests-e2e/tests/appRouter/trailing.test.ts | 15 +++++++++++++++ .../tests-e2e/tests/pagesRouter/trailing.test.ts | 7 +++++++ 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 packages/tests-e2e/tests/appRouter/trailing.test.ts diff --git a/packages/open-next/src/adapters/routing/matcher.ts b/packages/open-next/src/adapters/routing/matcher.ts index e4653ec9..0cc9d1e1 100644 --- a/packages/open-next/src/adapters/routing/matcher.ts +++ b/packages/open-next/src/adapters/routing/matcher.ts @@ -176,11 +176,12 @@ export function handleRedirects( !event.rawPath.endsWith("/") && !event.headers["x-nextjs-data"] ) { + const headersLocation = event.url.split('?'); return { type: event.type, statusCode: 308, headers: { - Location: event.url + "/", + Location: `${headersLocation[0]}/${headersLocation[1] ? `?${headersLocation[1]}` : ''}`, }, body: "", isBase64Encoded: false, @@ -191,11 +192,12 @@ export function handleRedirects( event.rawPath.endsWith("/") && event.rawPath !== "/" ) { + const headersLocation = event.url.split('?'); return { type: event.type, statusCode: 308, headers: { - Location: event.url.replace(/\/$/, ""), + Location: `${headersLocation[0].replace(/\/$/, "")}${headersLocation[1] ? `?${headersLocation[1]}` : ''}`, }, body: "", isBase64Encoded: false, diff --git a/packages/tests-e2e/README.md b/packages/tests-e2e/README.md index 799ba1c3..bd7ea2a8 100644 --- a/packages/tests-e2e/README.md +++ b/packages/tests-e2e/README.md @@ -37,8 +37,8 @@ export APP_PAGES_ROUTER_URL=$(jq -r '.["e2e-example-AppPagesRouter"].url' .sst/o ``` 3. Run the test ```bash -cd ../packages/tests-e2e -npm run e2e:dev +cd ../../packages/tests-e2e +pnpm run e2e:dev ``` diff --git a/packages/tests-e2e/tests/appRouter/trailing.test.ts b/packages/tests-e2e/tests/appRouter/trailing.test.ts new file mode 100644 index 00000000..b96d2e60 --- /dev/null +++ b/packages/tests-e2e/tests/appRouter/trailing.test.ts @@ -0,0 +1,15 @@ +import { expect, test } from "@playwright/test"; + +test("trailingSlash redirect", async ({ page }) => { + const response = await page.goto("/ssr/"); + + expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\/$/); + expect(response?.request().url()).toMatch(/\/ssr$/); +}); + +test("trailingSlash redirect with search parameters", async ({ page }) => { + const response = await page.goto("/ssr/?happy=true"); + + expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\/\?happy=true$/); + expect(response?.request().url()).toMatch(/\/ssr\?happy=true$/); +}); diff --git a/packages/tests-e2e/tests/pagesRouter/trailing.test.ts b/packages/tests-e2e/tests/pagesRouter/trailing.test.ts index 9267a319..0a1ea206 100644 --- a/packages/tests-e2e/tests/pagesRouter/trailing.test.ts +++ b/packages/tests-e2e/tests/pagesRouter/trailing.test.ts @@ -6,3 +6,10 @@ test("trailingSlash redirect", async ({ page }) => { expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr$/); expect(response?.request().url()).toMatch(/\/ssr\/$/); }); + +test("trailingSlash redirect with search parameters", async ({ page }) => { + const response = await page.goto("/ssr?happy=true"); + + expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\?happy=true$/); + expect(response?.request().url()).toMatch(/\/ssr\/\?happy=true$/); +}); \ No newline at end of file From e1875b9aebe09a3dd1b8fac8f8c043f18e0400c9 Mon Sep 17 00:00:00 2001 From: Alber Tenez Date: Fri, 13 Oct 2023 21:25:03 +0200 Subject: [PATCH 2/2] Fix eslint errors. --- packages/open-next/src/adapters/routing/matcher.ts | 12 ++++++++---- packages/tests-e2e/tests/appRouter/trailing.test.ts | 4 +++- .../tests-e2e/tests/pagesRouter/trailing.test.ts | 6 ++++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/open-next/src/adapters/routing/matcher.ts b/packages/open-next/src/adapters/routing/matcher.ts index 0cc9d1e1..680fa722 100644 --- a/packages/open-next/src/adapters/routing/matcher.ts +++ b/packages/open-next/src/adapters/routing/matcher.ts @@ -176,12 +176,14 @@ export function handleRedirects( !event.rawPath.endsWith("/") && !event.headers["x-nextjs-data"] ) { - const headersLocation = event.url.split('?'); + const headersLocation = event.url.split("?"); return { type: event.type, statusCode: 308, headers: { - Location: `${headersLocation[0]}/${headersLocation[1] ? `?${headersLocation[1]}` : ''}`, + Location: `${headersLocation[0]}/${ + headersLocation[1] ? `?${headersLocation[1]}` : "" + }`, }, body: "", isBase64Encoded: false, @@ -192,12 +194,14 @@ export function handleRedirects( event.rawPath.endsWith("/") && event.rawPath !== "/" ) { - const headersLocation = event.url.split('?'); + const headersLocation = event.url.split("?"); return { type: event.type, statusCode: 308, headers: { - Location: `${headersLocation[0].replace(/\/$/, "")}${headersLocation[1] ? `?${headersLocation[1]}` : ''}`, + Location: `${headersLocation[0].replace(/\/$/, "")}${ + headersLocation[1] ? `?${headersLocation[1]}` : "" + }`, }, body: "", isBase64Encoded: false, diff --git a/packages/tests-e2e/tests/appRouter/trailing.test.ts b/packages/tests-e2e/tests/appRouter/trailing.test.ts index b96d2e60..aeffc92e 100644 --- a/packages/tests-e2e/tests/appRouter/trailing.test.ts +++ b/packages/tests-e2e/tests/appRouter/trailing.test.ts @@ -10,6 +10,8 @@ test("trailingSlash redirect", async ({ page }) => { test("trailingSlash redirect with search parameters", async ({ page }) => { const response = await page.goto("/ssr/?happy=true"); - expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\/\?happy=true$/); + expect(response?.request().redirectedFrom()?.url()).toMatch( + /\/ssr\/\?happy=true$/, + ); expect(response?.request().url()).toMatch(/\/ssr\?happy=true$/); }); diff --git a/packages/tests-e2e/tests/pagesRouter/trailing.test.ts b/packages/tests-e2e/tests/pagesRouter/trailing.test.ts index 0a1ea206..5e1a01c6 100644 --- a/packages/tests-e2e/tests/pagesRouter/trailing.test.ts +++ b/packages/tests-e2e/tests/pagesRouter/trailing.test.ts @@ -10,6 +10,8 @@ test("trailingSlash redirect", async ({ page }) => { test("trailingSlash redirect with search parameters", async ({ page }) => { const response = await page.goto("/ssr?happy=true"); - expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\?happy=true$/); + expect(response?.request().redirectedFrom()?.url()).toMatch( + /\/ssr\?happy=true$/, + ); expect(response?.request().url()).toMatch(/\/ssr\/\?happy=true$/); -}); \ No newline at end of file +});