From 1f65018734339743e10a035fd93e216ed0f8c956 Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Thu, 17 Feb 2022 10:11:10 +0200 Subject: [PATCH 1/2] Remove deprecation for relative URL usage in middlewares --- errors/middleware-relative-urls.md | 4 ++-- packages/next/server/web/utils.ts | 11 +++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/errors/middleware-relative-urls.md b/errors/middleware-relative-urls.md index dabdf33060855bf..856bc94afaf3af1 100644 --- a/errors/middleware-relative-urls.md +++ b/errors/middleware-relative-urls.md @@ -2,11 +2,11 @@ #### Why This Error Occurred -You are using a Middleware function that uses `Response.redirect(url)`, `NextResponse.redirect(url)` or `NextResponse.rewrite(url)` where `url` is a relative or an invalid URL. Currently this will work, but building a request with `new Request(url)` or running `fetch(url)` when `url` is a relative URL will **not** work. For this reason and to bring consistency to Next.js Middleware, this behavior will be deprecated soon in favor of always using absolute URLs. +You are using a Middleware function that uses `Response.redirect(url)`, `NextResponse.redirect(url)` or `NextResponse.rewrite(url)` where `url` is a relative or an invalid URL. Prior to Next.js 12.1, we allowed passing relative URLs. However, constructing a request with `new Request(url)` or running `fetch(url)` when `url` is a relative URL **does not** work. For this reason and to bring consistency to Next.js Middleware, this behavior has been deprecated and now removed. #### Possible Ways to Fix It -To fix this warning you must always pass absolute URL for redirecting and rewriting. There are several ways to get the absolute URL but the recommended way is to clone `NextURL` and mutate it: +To fix this error you must always pass absolute URL for redirecting and rewriting. There are several ways to get the absolute URL but the recommended way is to clone `NextURL` and mutate it: ```typescript import type { NextRequest } from 'next/server' diff --git a/packages/next/server/web/utils.ts b/packages/next/server/web/utils.ts index 06e257457f09d12..0154442fd9a5689 100644 --- a/packages/next/server/web/utils.ts +++ b/packages/next/server/web/utils.ts @@ -149,18 +149,13 @@ export function splitCookiesString(cookiesString: string) { } /** - * We will be soon deprecating the usage of relative URLs in Middleware introducing - * URL validation. This helper puts the future code in place and prints a warning - * for cases where it will break. Meanwhile we preserve the previous behavior. + * Validate the correctness of a user-provided URL. */ export function validateURL(url: string | URL): string { try { return String(new URL(String(url))) } catch (error: any) { - console.log( - `warn -`, - 'using relative URLs for Middleware will be deprecated soon - https://nextjs.org/docs/messages/middleware-relative-urls' - ) - return String(url) + error.message = `URLs is malformed. Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls\n${error.message}` + throw error } } From 3a36f8db3c8ef22529b3d6473da33a5b597ce1c2 Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Thu, 17 Feb 2022 11:39:18 +0200 Subject: [PATCH 2/2] fix tests --- packages/next/server/web/utils.ts | 7 +++- .../core/pages/rewrites/_middleware.js | 2 +- .../middleware/core/test/index.test.js | 39 ++++++++++++++----- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/next/server/web/utils.ts b/packages/next/server/web/utils.ts index 0154442fd9a5689..a795ec35e144e42 100644 --- a/packages/next/server/web/utils.ts +++ b/packages/next/server/web/utils.ts @@ -155,7 +155,10 @@ export function validateURL(url: string | URL): string { try { return String(new URL(String(url))) } catch (error: any) { - error.message = `URLs is malformed. Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls\n${error.message}` - throw error + throw new Error( + `URLs is malformed. Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls`, + // @ts-expect-error This will work for people who enable the error causes polyfill + { cause: error } + ) } } diff --git a/test/integration/middleware/core/pages/rewrites/_middleware.js b/test/integration/middleware/core/pages/rewrites/_middleware.js index 27137642a1c144c..d9b83488318c5d5 100644 --- a/test/integration/middleware/core/pages/rewrites/_middleware.js +++ b/test/integration/middleware/core/pages/rewrites/_middleware.js @@ -12,7 +12,7 @@ export async function middleware(request) { ) { const isExternal = url.searchParams.get('override') === 'external' return NextResponse.rewrite( - isExternal ? 'https://vercel.com' : '/rewrites/a' + isExternal ? 'https://vercel.com' : new URL('/rewrites/a', request.url) ) } diff --git a/test/integration/middleware/core/test/index.test.js b/test/integration/middleware/core/test/index.test.js index c6d33990720f175..805cf48fd3954c4 100644 --- a/test/integration/middleware/core/test/index.test.js +++ b/test/integration/middleware/core/test/index.test.js @@ -19,7 +19,7 @@ const context = {} context.appDir = join(__dirname, '../') const middlewareWarning = 'using beta Middleware (not covered by semver)' -const urlsWarning = 'using relative URLs for Middleware will be deprecated soon' +const urlsError = 'Please use only absolute URLs' describe('Middleware base tests', () => { describe('dev mode', () => { @@ -110,7 +110,7 @@ describe('Middleware base tests', () => { }) }) -function urlTests(log, locale = '') { +function urlTests(_log, locale = '') { it('rewrites by default to a target location', async () => { const res = await fetchViaHTTP(context.appPort, `${locale}/urls`) const html = await res.text() @@ -146,18 +146,39 @@ function urlTests(log, locale = '') { }) it('warns when using Response.redirect with a relative URL', async () => { - await fetchViaHTTP(context.appPort, `${locale}/urls/relative-redirect`) - expect(log.output).toContain(urlsWarning) + const response = await fetchViaHTTP( + context.appPort, + `${locale}/urls/relative-redirect` + ) + expect(await response.json()).toEqual({ + error: { + message: expect.stringContaining(urlsError), + }, + }) }) it('warns when using NextResponse.redirect with a relative URL', async () => { - await fetchViaHTTP(context.appPort, `${locale}/urls/relative-next-redirect`) - expect(log.output).toContain(urlsWarning) + const response = await fetchViaHTTP( + context.appPort, + `${locale}/urls/relative-next-redirect` + ) + expect(await response.json()).toEqual({ + error: { + message: expect.stringContaining(urlsError), + }, + }) }) - it('warns when using NextResponse.rewrite with a relative URL', async () => { - await fetchViaHTTP(context.appPort, `${locale}/urls/relative-next-rewrite`) - expect(log.output).toContain(urlsWarning) + it('throws when using NextResponse.rewrite with a relative URL', async () => { + const response = await fetchViaHTTP( + context.appPort, + `${locale}/urls/relative-next-rewrite` + ) + expect(await response.json()).toEqual({ + error: { + message: expect.stringContaining(urlsError), + }, + }) }) }