Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: strip _rsc query for client navigation rsc request #65084

Merged
merged 4 commits into from
Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/next/src/build/swc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1338,15 +1338,15 @@ function loadNative(importPath?: string) {
try {
// Use the binary directly to skip `pnpm pack` for testing as it's slow because of the large native binary.
bindings = require(`${NEXT_TEST_NATIVE_DIR}/next-swc.${triple.platformArchABI}.node`)
console.log(
infoLog(
'next-swc build: local built @next/swc from NEXT_TEST_NATIVE_DIR'
)
break
} catch (e) {}
} else {
try {
bindings = require(`@next/swc/native/next-swc.${triple.platformArchABI}.node`)
console.log('next-swc build: local built @next/swc')
infoLog('next-swc build: local built @next/swc')
break
} catch (e) {}
}
Expand Down
11 changes: 10 additions & 1 deletion packages/next/src/lib/url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const DUMMY_ORIGIN = 'http://n'
import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'

export const DUMMY_ORIGIN = 'http://n'

function getUrlWithoutHost(url: string) {
return new URL(url, DUMMY_ORIGIN)
Expand All @@ -11,3 +13,10 @@ export function getPathname(url: string) {
export function isFullStringUrl(url: string) {
return /https?:\/\//.test(url)
}

export function stripNextRscUnionQuery(relativeUrl: string): string {
const urlInstance = new URL(relativeUrl, DUMMY_ORIGIN)
urlInstance.searchParams.delete(NEXT_RSC_UNION_QUERY)

return urlInstance.pathname + urlInstance.search
}
18 changes: 14 additions & 4 deletions packages/next/src/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ import { interopDefault } from '../lib/interop-default'
import { formatDynamicImportPath } from '../lib/format-dynamic-import-path'
import type { NextFontManifest } from '../build/webpack/plugins/next-font-manifest-plugin'
import { isInterceptionRouteRewrite } from '../lib/generate-interception-routes-rewrites'
import { stripNextRscUnionQuery } from '../lib/url'

export * from './base-server'

Expand Down Expand Up @@ -1123,9 +1124,9 @@ export default class NextNodeServer extends BaseServer<
// we don't log for non-route requests
const routeMatch = getRequestMeta(req).match

const isRSC = isRSCRequestCheck(normalizedReq)
if (!routeMatch || isRSC || isMiddlewareRequest) return
if (!routeMatch || isMiddlewareRequest) return

const isRSC = isRSCRequestCheck(normalizedReq)
const reqEnd = Date.now()
const fetchMetrics = normalizedReq.fetchMetrics || []
const reqDuration = reqEnd - reqStart
Expand All @@ -1140,9 +1141,14 @@ export default class NextNodeServer extends BaseServer<

const color = statusColor(res.statusCode)
const method = req.method || 'GET'
const requestUrl = req.url || ''
const loggingUrl = isRSC
? stripNextRscUnionQuery(requestUrl)
: requestUrl

writeStdoutLine(
`${method} ${req.url ?? ''} ${color(
(res.statusCode ?? 200).toString()
`${method} ${loggingUrl} ${color(
res.statusCode.toString()
)} in ${reqDuration}ms`
)

Expand Down Expand Up @@ -1798,6 +1804,10 @@ export default class NextNodeServer extends BaseServer<
? `https://${req.headers.host || 'localhost'}${req.url}`
: req.url

const isRSC = isRSCRequestCheck(req)
if (isRSC) {
addRequestMeta(req, 'isRSCRequest', true)
}
addRequestMeta(req, 'initURL', initUrl)
addRequestMeta(req, 'initQuery', { ...parsedUrl.query })
addRequestMeta(req, 'initProtocol', protocol)
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/app-dir/logging/app/headers/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { headers } from 'next/headers'

export default function Page() {
headers()
return <p>{'headers()'}</p>
}
24 changes: 23 additions & 1 deletion test/e2e/app-dir/logging/app/layout.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
import Link from 'next/link'

export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
<body>
<header>
<Link id="nav-link" href={'/link'}>
/link
</Link>
<br />
<Link id="nav-headers" href={'/headers'}>
/headers
</Link>
<br />
<Link id="nav-default-cache" href={'/default-cache'}>
/default-cache
</Link>
<br />
<Link id="nav-cache-revalidate" href={'/cache-revalidate'}>
/cache-revalidate
</Link>
<br />
</header>
<div>{children}</div>
</body>
</html>
)
}
6 changes: 5 additions & 1 deletion test/e2e/app-dir/logging/app/link/page.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Link from 'next/link'

export default function Page() {
return <Link href="/foo">Trigger RSC request</Link>
return (
<Link id="foo" href="/foo">
Trigger RSC request
</Link>
)
}
18 changes: 16 additions & 2 deletions test/e2e/app-dir/logging/fetch-logging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,16 +167,30 @@ describe('app-dir - logging', () => {
})
})

it('should exlucde Middleware invoked and _rsc requests', async () => {
it('should exclude Middleware invoked and _rsc requests', async () => {
const outputIndex = next.cliOutput.length

const browser = await next.browser('/link')
await browser.elementByCss('a').click()
await browser.elementByCss('a#foo').click()
await browser.waitForElementByCss('h2')
const logs = stripAnsi(next.cliOutput.slice(outputIndex))
expect(logs).not.toContain('/_next/static')
expect(logs).not.toContain('?_rsc')
})

it('should not log _rsc query for client navigation RSC request', async () => {
const outputIndex = next.cliOutput.length

const browser = await next.browser('/')
await browser.elementByCss('a#nav-headers').click()
await browser.waitForElementByCss('p')
const logs = stripAnsi(next.cliOutput.slice(outputIndex))

expect(logs).toContain('GET /')
expect(logs).toContain('GET /headers')
expect(logs).not.toContain('/_next/static')
expect(logs).not.toContain('?_rsc')
})
}
} else {
// No fetches logging enabled
Expand Down