From b04ff40909bf553523f435fa5b51ff35c6cc0cd8 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 10 May 2023 13:56:04 -0500 Subject: [PATCH 1/2] fix: strip domain from ipx edge functions path (#2098) --- packages/runtime/src/helpers/edge.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/runtime/src/helpers/edge.ts b/packages/runtime/src/helpers/edge.ts index 6a139ced05..3e2c33f740 100644 --- a/packages/runtime/src/helpers/edge.ts +++ b/packages/runtime/src/helpers/edge.ts @@ -93,6 +93,11 @@ export const loadPrerenderManifest = (netlifyConfig: NetlifyConfig): Promise
 `next_${name.replace(/\W/g, '_')}`
 
+/**
+ * Convert the images path to strip the origin (until domain-level Edge functions are supported)
+ */
+const sanitizeEdgePath = (imagesPath: string) => new URL(imagesPath, process.env.URL || 'http://n').pathname
+
 // Slightly different spacing in different versions!
 const IMPORT_UNSUPPORTED = [
   `Object.defineProperty(globalThis,"__import_unsupported"`,
@@ -485,10 +490,11 @@ export const writeEdgeFunctions = async ({
       join('.netlify', 'functions-internal', IMAGE_FUNCTION_NAME, 'imageconfig.json'),
       join(edgeFunctionDir, 'imageconfig.json'),
     )
+
     manifest.functions.push({
       function: 'ipx',
       name: 'next/image handler',
-      path: nextConfig.images.path || '/_next/image',
+      path: nextConfig.images.path ? sanitizeEdgePath(nextConfig.images.path) : '/_next/image',
       generator,
     })
 

From 5ff82938c567cf89c05b5a0da7d2cb1501ddb5a5 Mon Sep 17 00:00:00 2001
From: Zach Leatherman 
Date: Wed, 7 Jun 2023 16:45:06 -0500
Subject: [PATCH 2/2] chore: add unit tests for sanitizer for #2098

---
 packages/runtime/src/helpers/edge.ts |  2 +-
 test/helpers/matchers.spec.ts        | 23 ++++++++++++++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/packages/runtime/src/helpers/edge.ts b/packages/runtime/src/helpers/edge.ts
index 212f760a0c..628f94706e 100644
--- a/packages/runtime/src/helpers/edge.ts
+++ b/packages/runtime/src/helpers/edge.ts
@@ -96,7 +96,7 @@ const sanitizeName = (name: string) => `next_${name.replace(/\W/g, '_')}`
 /**
  * Convert the images path to strip the origin (until domain-level Edge functions are supported)
  */
-const sanitizeEdgePath = (imagesPath: string) => new URL(imagesPath, process.env.URL || 'http://n').pathname
+export const sanitizeEdgePath = (imagesPath: string) => new URL(imagesPath, process.env.URL || 'http://n').pathname
 
 // Slightly different spacing in different versions!
 const IMPORT_UNSUPPORTED = [
diff --git a/test/helpers/matchers.spec.ts b/test/helpers/matchers.spec.ts
index 96cbca77a9..4b6a44e070 100644
--- a/test/helpers/matchers.spec.ts
+++ b/test/helpers/matchers.spec.ts
@@ -1,4 +1,4 @@
-import { getEdgeFunctionPatternForPage } from '../../packages/runtime/src/helpers/edge'
+import { getEdgeFunctionPatternForPage, sanitizeEdgePath } from '../../packages/runtime/src/helpers/edge'
 import { makeLocaleOptional, stripLookahead } from '../../packages/runtime/src/helpers/matchers'
 
 const makeDataPath = (path: string) => `/_next/data/build-id${path === '/' ? '/index' : path}.json`
@@ -183,3 +183,24 @@ describe('the edge function matcher helpers', () => {
     expect('/edge/1/').toMatch(new RegExp(regex))
   })
 })
+
+describe('the images path is sanitized', () => {
+  it('passes through a path', () => {
+    expect(sanitizeEdgePath('/_next/image')).toBe('/_next/image')
+  })
+
+  it('strips domains', () => {
+    expect(sanitizeEdgePath('http://example.com/_next/image')).toBe('/_next/image')
+    expect(sanitizeEdgePath('https://example.com/_next/image')).toBe('/_next/image')
+  })
+
+  it('strips domains with globs', () => {
+    expect(sanitizeEdgePath('http://example.com/_next/image/*')).toBe('/_next/image/*')
+    expect(sanitizeEdgePath('https://example.com/_next/image/*')).toBe('/_next/image/*')
+  })
+
+  it('strips domains with tokens', () => {
+    expect(sanitizeEdgePath('http://example.com/_next/image/:slug/')).toBe('/_next/image/:slug/')
+    expect(sanitizeEdgePath('https://example.com/_next/image/:slug/')).toBe('/_next/image/:slug/')
+  })
+})