From 39b09b90b7c957b96b08d4997a9fc9d3b9bda36a Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 14 Aug 2022 21:11:46 +0200 Subject: [PATCH 1/3] code refactoring --- packages/next/server/next-server.ts | 391 ++++++++++++++-------------- 1 file changed, 199 insertions(+), 192 deletions(-) diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 3b67eda39e52d94..7dff6b91a5b3295 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -1184,13 +1184,6 @@ export default class NextNodeServer extends BaseServer { }) } - protected getEdgeRoutes(): RoutingItem[] { - const edgeFunctions = this.getEdgeFunctions() - const middleware = this.getMiddleware() - - return edgeFunctions.concat(middleware ? [middleware] : []) - } - /** * Get information for the edge function located in the provided page * folder. If the edge function info can't be found it will throw @@ -1385,218 +1378,232 @@ export default class NextNodeServer extends BaseServer { protected generateCatchAllMiddlewareRoute(devReady?: boolean): Route[] { if (this.minimalMode) return [] + const routes = [] + if (!this.renderOpts.dev || devReady) { + if (this.getMiddleware()) { + const middlewareCatchAllRoute: Route = { + match: getPathMatch('/:path*'), + matchesBasePath: true, + matchesLocale: true, + type: 'route', + name: 'middleware catchall', + fn: async (req, res, _params, parsed) => { + const middleware = this.getMiddleware() + if (!middleware) { + return { finished: false } + } - const edgeCatchAllRoute: Route = { - match: getPathMatch('/:path*'), - type: 'route', - name: 'edge functions catchall', - fn: async (req, res, _params, parsed) => { - const edgeFunctions = this.getEdgeFunctions() - if (!edgeFunctions.length) return { finished: false } - - const { query, pathname } = parsed - const normalizedPathname = removeTrailingSlash(pathname || '') - let page = normalizedPathname - let params: Params | undefined = undefined - - for (const edgeFunction of edgeFunctions) { - const matched = edgeFunction.match(page) - if (matched) { - params = matched - page = edgeFunction.page - break - } - } - - const edgeSSRResult = await this.runEdgeFunction({ - req, - res, - query, - params, - page, - }) - - return { - finished: !!edgeSSRResult, - } - }, - } + const initUrl = getRequestMeta(req, '__NEXT_INIT_URL')! + const parsedUrl = parseUrl(initUrl) + const pathnameInfo = getNextPathnameInfo(parsedUrl.pathname, { + nextConfig: this.nextConfig, + }) - const middlewareCatchAllRoute: Route = { - match: getPathMatch('/:path*'), - matchesBasePath: true, - matchesLocale: true, - type: 'route', - name: 'middleware catchall', - fn: async (req, res, _params, parsed) => { - const middleware = this.getMiddleware() - if (!middleware) { - return { finished: false } - } + parsedUrl.pathname = pathnameInfo.pathname + const normalizedPathname = removeTrailingSlash( + parsed.pathname || '' + ) + if (!middleware.match(normalizedPathname)) { + return { finished: false } + } - const initUrl = getRequestMeta(req, '__NEXT_INIT_URL')! - const parsedUrl = parseUrl(initUrl) - const pathnameInfo = getNextPathnameInfo(parsedUrl.pathname, { - nextConfig: this.nextConfig, - }) + let result: Awaited< + ReturnType + > - parsedUrl.pathname = pathnameInfo.pathname - const normalizedPathname = removeTrailingSlash(parsed.pathname || '') - if (!middleware.match(normalizedPathname)) { - return { finished: false } - } + try { + result = await this.runMiddleware({ + request: req, + response: res, + parsedUrl: parsedUrl, + parsed: parsed, + }) + } catch (err) { + if (isError(err) && err.code === 'ENOENT') { + await this.render404(req, res, parsed) + return { finished: true } + } - let result: Awaited< - ReturnType - > + if (err instanceof DecodeError) { + res.statusCode = 400 + this.renderError(err, req, res, parsed.pathname || '') + return { finished: true } + } - try { - result = await this.runMiddleware({ - request: req, - response: res, - parsedUrl: parsedUrl, - parsed: parsed, - }) - } catch (err) { - if (isError(err) && err.code === 'ENOENT') { - await this.render404(req, res, parsed) - return { finished: true } - } + const error = getProperError(err) + console.error(error) + res.statusCode = 500 + this.renderError(error, req, res, parsed.pathname || '') + return { finished: true } + } - if (err instanceof DecodeError) { - res.statusCode = 400 - this.renderError(err, req, res, parsed.pathname || '') - return { finished: true } - } + if ('finished' in result) { + return result + } - const error = getProperError(err) - console.error(error) - res.statusCode = 500 - this.renderError(error, req, res, parsed.pathname || '') - return { finished: true } - } + if (result.response.headers.has('x-middleware-rewrite')) { + const value = result.response.headers.get('x-middleware-rewrite')! + const rel = relativizeURL(value, initUrl) + result.response.headers.set('x-middleware-rewrite', rel) + } - if ('finished' in result) { - return result - } + if (result.response.headers.has('Location')) { + const value = result.response.headers.get('Location')! + const rel = relativizeURL(value, initUrl) + result.response.headers.set('Location', rel) + } - if (result.response.headers.has('x-middleware-rewrite')) { - const value = result.response.headers.get('x-middleware-rewrite')! - const rel = relativizeURL(value, initUrl) - result.response.headers.set('x-middleware-rewrite', rel) - } + if ( + !result.response.headers.has('x-middleware-rewrite') && + !result.response.headers.has('x-middleware-next') && + !result.response.headers.has('Location') + ) { + result.response.headers.set('x-middleware-refresh', '1') + } - if (result.response.headers.has('Location')) { - const value = result.response.headers.get('Location')! - const rel = relativizeURL(value, initUrl) - result.response.headers.set('Location', rel) - } + result.response.headers.delete('x-middleware-next') + + for (const [key, value] of Object.entries( + toNodeHeaders(result.response.headers) + )) { + if ( + [ + 'x-middleware-rewrite', + 'x-middleware-redirect', + 'x-middleware-refresh', + ].includes(key) + ) { + continue + } + if (key !== 'content-encoding' && value !== undefined) { + res.setHeader(key, value) + } + } - if ( - !result.response.headers.has('x-middleware-rewrite') && - !result.response.headers.has('x-middleware-next') && - !result.response.headers.has('Location') - ) { - result.response.headers.set('x-middleware-refresh', '1') - } + res.statusCode = result.response.status + res.statusMessage = result.response.statusText - result.response.headers.delete('x-middleware-next') + const location = result.response.headers.get('Location') + if (location) { + res.statusCode = result.response.status + if (res.statusCode === 308) { + res.setHeader('Refresh', `0;url=${location}`) + } - for (const [key, value] of Object.entries( - toNodeHeaders(result.response.headers) - )) { - if ( - [ - 'x-middleware-rewrite', - 'x-middleware-redirect', - 'x-middleware-refresh', - ].includes(key) - ) { - continue - } - if (key !== 'content-encoding' && value !== undefined) { - res.setHeader(key, value) - } - } + res.body(location).send() + return { + finished: true, + } + } - res.statusCode = result.response.status - res.statusMessage = result.response.statusText + if (result.response.headers.has('x-middleware-rewrite')) { + const rewritePath = result.response.headers.get( + 'x-middleware-rewrite' + )! + const parsedDestination = parseUrl(rewritePath) + const newUrl = parsedDestination.pathname + + if ( + parsedDestination.protocol && + (parsedDestination.port + ? `${parsedDestination.hostname}:${parsedDestination.port}` + : parsedDestination.hostname) !== req.headers.host + ) { + return this.proxyRequest( + req as NodeNextRequest, + res as NodeNextResponse, + parsedDestination + ) + } - const location = result.response.headers.get('Location') - if (location) { - res.statusCode = result.response.status - if (res.statusCode === 308) { - res.setHeader('Refresh', `0;url=${location}`) - } + if (this.nextConfig.i18n) { + const localePathResult = normalizeLocalePath( + newUrl, + this.nextConfig.i18n.locales + ) + if (localePathResult.detectedLocale) { + parsedDestination.query.__nextLocale = + localePathResult.detectedLocale + } + } - res.body(location).send() - return { - finished: true, - } - } + addRequestMeta(req, '_nextRewroteUrl', newUrl) + addRequestMeta(req, '_nextDidRewrite', newUrl !== req.url) - if (result.response.headers.has('x-middleware-rewrite')) { - const rewritePath = result.response.headers.get( - 'x-middleware-rewrite' - )! - const parsedDestination = parseUrl(rewritePath) - const newUrl = parsedDestination.pathname + return { + finished: false, + pathname: newUrl, + query: parsedDestination.query, + } + } - if ( - parsedDestination.protocol && - (parsedDestination.port - ? `${parsedDestination.hostname}:${parsedDestination.port}` - : parsedDestination.hostname) !== req.headers.host - ) { - return this.proxyRequest( - req as NodeNextRequest, - res as NodeNextResponse, - parsedDestination - ) - } + if (result.response.headers.has('x-middleware-refresh')) { + res.statusCode = result.response.status + for await (const chunk of result.response.body || ([] as any)) { + this.streamResponseChunk(res as NodeNextResponse, chunk) + } + res.send() + return { + finished: true, + } + } - if (this.nextConfig.i18n) { - const localePathResult = normalizeLocalePath( - newUrl, - this.nextConfig.i18n.locales - ) - if (localePathResult.detectedLocale) { - parsedDestination.query.__nextLocale = - localePathResult.detectedLocale + return { + finished: false, } - } + }, + } - addRequestMeta(req, '_nextRewroteUrl', newUrl) - addRequestMeta(req, '_nextDidRewrite', newUrl !== req.url) + routes.push(middlewareCatchAllRoute) + } + if (this.getEdgeFunctions().length) { + const edgeCatchAllRoute: Route = { + match: getPathMatch('/:path*'), + type: 'route', + name: 'edge functions catchall', + fn: async (req, res, _params, parsed) => { + const edgeFunctions = this.getEdgeFunctions() + if (!edgeFunctions.length) return { finished: false } + + const { query, pathname } = parsed + const normalizedPathname = removeTrailingSlash(pathname || '') + let page = normalizedPathname + let params: Params | undefined = undefined + let pageFound = !isDynamicRoute(page) + + if (this.dynamicRoutes) { + for (const dynamicRoute of this.dynamicRoutes) { + params = dynamicRoute.match(normalizedPathname) || undefined + if (params) { + page = dynamicRoute.page + pageFound = true + break + } + } + } - return { - finished: false, - pathname: newUrl, - query: parsedDestination.query, - } - } + if (!pageFound) { + return { + finished: false, + } + } - if (result.response.headers.has('x-middleware-refresh')) { - res.statusCode = result.response.status - for await (const chunk of result.response.body || ([] as any)) { - this.streamResponseChunk(res as NodeNextResponse, chunk) - } - res.send() - return { - finished: true, - } - } + const edgeSSRResult = await this.runEdgeFunction({ + req, + res, + query, + params, + page, + }) - return { - finished: false, + return { + finished: !!edgeSSRResult, + } + }, } - }, - } - const routes = [] - if (!this.renderOpts.dev || devReady) { - if (this.getMiddleware()) routes[0] = middlewareCatchAllRoute - if (this.getEdgeFunctions().length) routes[1] = edgeCatchAllRoute + routes.push(edgeCatchAllRoute) + } } return routes From 2e8fe69b895d406745abecb72444a05c32e0a34f Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 15 Aug 2022 18:09:45 +0100 Subject: [PATCH 2/3] merge canary --- packages/next/server/next-server.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 7dff6b91a5b3295..932f29c4a0facde 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -86,6 +86,7 @@ import { bodyStreamToNodeStream, getClonableBody } from './body-streams' import { checkIsManualRevalidate } from './api-utils' import { shouldUseReactRoot } from './utils' import ResponseCache from './response-cache' +import { isDynamicRoute } from '../shared/lib/router/utils' import { IncrementalCache } from './lib/incremental-cache' import { getSortedRoutes } from '../shared/lib/router/utils/sorted-routes' From a2b9e225a5d1aa0ff3f88c7be425b42393bdaba1 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 15 Aug 2022 18:13:29 +0100 Subject: [PATCH 3/3] resolve conflicts --- packages/next/server/next-server.ts | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index 932f29c4a0facde..e4242336f8369ff 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -86,7 +86,6 @@ import { bodyStreamToNodeStream, getClonableBody } from './body-streams' import { checkIsManualRevalidate } from './api-utils' import { shouldUseReactRoot } from './utils' import ResponseCache from './response-cache' -import { isDynamicRoute } from '../shared/lib/router/utils' import { IncrementalCache } from './lib/incremental-cache' import { getSortedRoutes } from '../shared/lib/router/utils/sorted-routes' @@ -1570,22 +1569,13 @@ export default class NextNodeServer extends BaseServer { const normalizedPathname = removeTrailingSlash(pathname || '') let page = normalizedPathname let params: Params | undefined = undefined - let pageFound = !isDynamicRoute(page) - - if (this.dynamicRoutes) { - for (const dynamicRoute of this.dynamicRoutes) { - params = dynamicRoute.match(normalizedPathname) || undefined - if (params) { - page = dynamicRoute.page - pageFound = true - break - } - } - } - if (!pageFound) { - return { - finished: false, + for (const edgeFunction of edgeFunctions) { + const matched = edgeFunction.match(page) + if (matched) { + params = matched + page = edgeFunction.page + break } }