Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 681fbbd

Browse files
authored
Fix basePath and public folder check ending routes early (#16356)
This corrects the basePath being required check for filesystem routes to not consider the public folder catch-all route since it always matches even if the public file isn't present and instead moves the basePath check inside of the public-folder catch-all. Tests already exist that catch this by adding a public folder to the existing `basepath` test suite Fixes: #16332 Closes: #16350
1 parent 0226e78 commit 681fbbd

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

packages/next/next-server/server/next-server.ts

+8
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,14 @@ export default class Server {
783783
name: 'public folder catchall',
784784
fn: async (req, res, params, parsedUrl) => {
785785
const pathParts: string[] = params.path || []
786+
const { basePath } = this.nextConfig
787+
788+
// if basePath is defined require it be present
789+
if (basePath) {
790+
if (pathParts[0] !== basePath.substr(1)) return { finished: false }
791+
pathParts.shift()
792+
}
793+
786794
const path = `/${pathParts.join('/')}`
787795

788796
if (publicFiles.has(path)) {

packages/next/next-server/server/router.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export type PageChecker = (pathname: string) => Promise<boolean>
3737
const customRouteTypes = new Set(['rewrite', 'redirect', 'header'])
3838

3939
function replaceBasePath(basePath: string, pathname: string) {
40+
// If replace ends up replacing the full url it'll be `undefined`, meaning we have to default it to `/`
4041
return pathname!.replace(basePath, '') || '/'
4142
}
4243

@@ -166,9 +167,10 @@ export default class Router {
166167
const originalPathname = currentPathname
167168
const requireBasePath = testRoute.requireBasePath !== false
168169
const isCustomRoute = customRouteTypes.has(testRoute.type)
170+
const isPublicFolderCatchall = testRoute.name === 'public folder catchall'
171+
const keepBasePath = isCustomRoute || isPublicFolderCatchall
169172

170-
if (!isCustomRoute) {
171-
// If replace ends up replacing the full url it'll be `undefined`, meaning we have to default it to `/`
173+
if (!keepBasePath) {
172174
currentPathname = replaceBasePath(this.basePath, currentPathname!)
173175
}
174176

@@ -178,7 +180,7 @@ export default class Router {
178180
if (newParams) {
179181
// since we require basePath be present for non-custom-routes we
180182
// 404 here when we matched an fs route
181-
if (!isCustomRoute) {
183+
if (!keepBasePath) {
182184
if (!originallyHadBasePath && !(req as any)._nextDidRewrite) {
183185
if (requireBasePath) {
184186
// consider this a non-match so the 404 renders
@@ -201,7 +203,7 @@ export default class Router {
201203

202204
// since the fs route didn't match we need to re-add the basePath
203205
// to continue checking rewrites with the basePath present
204-
if (!isCustomRoute) {
206+
if (!keepBasePath) {
205207
parsedUrlUpdated.pathname = originalPathname
206208
}
207209

@@ -272,7 +274,6 @@ export default class Router {
272274
}
273275
}
274276
}
275-
276277
return false
277278
}
278279
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world

test/integration/basepath/test/index.test.js

+11
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ const runTests = (context, dev = false) => {
135135
})
136136
}
137137

138+
it('should 404 for public file without basePath', async () => {
139+
const res = await fetchViaHTTP(context.appPort, '/data.txt')
140+
expect(res.status).toBe(404)
141+
})
142+
143+
it('should serve public file with basePath correctly', async () => {
144+
const res = await fetchViaHTTP(context.appPort, '/docs/data.txt')
145+
expect(res.status).toBe(200)
146+
expect(await res.text()).toBe('hello world')
147+
})
148+
138149
it('should rewrite with basePath by default', async () => {
139150
const html = await renderViaHTTP(context.appPort, '/docs/rewrite-1')
140151
expect(html).toContain('getServerSideProps')

0 commit comments

Comments
 (0)