Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7fe6b3b

Browse files
serhalpmrstork
andauthored
fix(edge-runtime): match path with URI-encoded chars (#2873)
Following the behaviour invercel/next.js#78325, if a pathmatches a configured middleware matcher when URI-decoded, consider it a match.This doesn't seem ideal, but it aligns our behaviour with that of Next.js, and ensuresthat static asset matching behaviour aligns with edge middleware matching behaviour.Co-authored-by: Mateusz Bocian <mrstork@users.noreply.github.com>
1 parent5dac3e3 commit7fe6b3b

File tree

10 files changed

+74
-5
lines changed

10 files changed

+74
-5
lines changed

‎edge-runtime/lib/routing.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,24 @@ export interface MiddlewareMatcher {
424424
missing?:RouteHas[]
425425
}
426426

427+
constdecodeMaybeEncodedPath=(path:string):string=>{
428+
try{
429+
returndecodeURIComponent(path)
430+
}catch{
431+
returnpath
432+
}
433+
}
434+
427435
exportfunctiongetMiddlewareRouteMatcher(matchers:MiddlewareMatcher[]):MiddlewareRouteMatch{
428436
return(
429-
pathname:string|null|undefined,
437+
unsafePathname:string|null|undefined,
430438
req:Pick<Request,'headers'|'url'>,
431439
query:Params,
432440
)=>{
441+
constpathname=decodeMaybeEncodedPath(unsafePathname??'')
442+
433443
for(constmatcherofmatchers){
434-
constrouteMatch=newRegExp(matcher.regexp).exec(pathname!)
444+
constrouteMatch=newRegExp(matcher.regexp).exec(pathname)
435445
if(!routeMatch){
436446
continue
437447
}

‎tests/e2e/edge-middleware.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,15 @@ test("requests with x-middleware-subrequest don't skip middleware (GHSA-f82v-jwr
233233
expect(response.headers.get('x-test-used-next-version')).toBe('15.2.2')
234234
})
235235

236+
test('requests with different encoding than matcher match anyway',async({
237+
middlewareStaticAssetMatcher,
238+
})=>{
239+
constresponse=awaitfetch(`${middlewareStaticAssetMatcher.url}/hello%2Fworld.txt`)
240+
241+
// middleware was not skipped
242+
expect(awaitresponse.text()).toBe('hello from middleware')
243+
})
244+
236245
test.describe('RSC cache poisoning',()=>{
237246
test('Middleware rewrite',async({ page, middleware})=>{
238247
constprefetchResponsePromise=newPromise<Response>((resolve)=>{

‎tests/fixtures/middleware-og/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
"build":"next build"
99
},
1010
"dependencies": {
11-
"@aws-amplify/adapter-nextjs":"^1.0.18",
12-
"aws-amplify":"^6.0.18",
1311
"next":"latest",
1412
"react":"18.2.0",
1513
"react-dom":"18.2.0"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
exportconstmetadata={
2+
title:'Simple Next App',
3+
description:'Description for Simple Next App',
4+
}
5+
6+
exportdefaultfunctionRootLayout({ children}){
7+
return(
8+
<htmllang="en">
9+
<body>{children}</body>
10+
</html>
11+
)
12+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
exportdefaultfunctionHome(){
2+
return(
3+
<main>
4+
<h1>Home</h1>
5+
</main>
6+
)
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
exportdefaultfunctionmiddleware(){
2+
returnnewResponse('hello from middleware')
3+
}
4+
5+
exportconstconfig={
6+
matcher:'/hello/world.txt',
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**@type {import('next').NextConfig} */
2+
constnextConfig={
3+
output:'standalone',
4+
eslint:{
5+
ignoreDuringBuilds:true,
6+
},
7+
}
8+
9+
module.exports=nextConfig
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name":"middleware",
3+
"version":"0.1.0",
4+
"private":true,
5+
"scripts": {
6+
"postinstall":"next build",
7+
"dev":"next dev",
8+
"build":"next build"
9+
},
10+
"dependencies": {
11+
"next":"latest",
12+
"react":"18.2.0",
13+
"react-dom":"18.2.0"
14+
}
15+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello from a static asset

‎tests/utils/create-e2e-fixture.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,11 @@ export const fixtureFactories = {
333333
pnpm:()=>createE2EFixture('pnpm',{packageManger:'pnpm'}),
334334
bun:()=>createE2EFixture('simple',{packageManger:'bun'}),
335335
middleware:()=>createE2EFixture('middleware'),
336-
middlewareSubrequestVuln:()=>createE2EFixture('middleware-subrequest-vuln'),
337336
middlewareI18nExcludedPaths:()=>createE2EFixture('middleware-i18n-excluded-paths'),
338337
middlewareOg:()=>createE2EFixture('middleware-og'),
339338
middlewarePages:()=>createE2EFixture('middleware-pages'),
339+
middlewareStaticAssetMatcher:()=>createE2EFixture('middleware-static-asset-matcher'),
340+
middlewareSubrequestVuln:()=>createE2EFixture('middleware-subrequest-vuln'),
340341
pageRouter:()=>createE2EFixture('page-router'),
341342
pageRouterBasePathI18n:()=>createE2EFixture('page-router-base-path-i18n'),
342343
turborepo:()=>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp