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 hmr assetPrefix escaping and reuse logic from other files #67983

Merged
merged 10 commits into from
Jul 30, 2024
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { normalizedAssetPrefix } from '../../../../../shared/lib/normalized-asset-prefix'

function getSocketProtocol(assetPrefix: string): string {
let protocol = window.location.protocol

Expand All @@ -9,18 +11,16 @@ function getSocketProtocol(assetPrefix: string): string {
return protocol === 'http:' ? 'ws' : 'wss'
}

export function getSocketUrl(assetPrefix: string): string {
export function getSocketUrl(assetPrefix: string | undefined): string {
const { hostname, port } = window.location
const protocol = getSocketProtocol(assetPrefix)
const normalizedAssetPrefix = assetPrefix.replace(/^\/+/, '')

let url = `${protocol}://${hostname}:${port}${
normalizedAssetPrefix ? `/${normalizedAssetPrefix}` : ''
}`
const protocol = getSocketProtocol(assetPrefix || '')
const prefix = normalizedAssetPrefix(assetPrefix)

if (normalizedAssetPrefix.startsWith('http')) {
url = `${protocol}://${normalizedAssetPrefix.split('://', 2)[1]}`
// if original assetPrefix is a full URL with protocol
// we just update to use the correct `ws` protocol
if (assetPrefix?.replace(/^\/+/, '').includes('://')) {
return `${protocol}://${prefix}`
}

return url
return `${protocol}://${hostname}:${port}${prefix}`
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import type { HMR_ACTION_TYPES } from '../../../../server/dev/hot-reloader-types'
import { getSocketUrl } from '../internal/helpers/get-socket-url'

let source: WebSocket

type ActionCallback = (action: HMR_ACTION_TYPES) => void

const eventCallbacks: Array<ActionCallback> = []

function getSocketProtocol(assetPrefix: string): string {
let protocol = location.protocol

try {
// assetPrefix is a url
protocol = new URL(assetPrefix).protocol
} catch {}

return protocol === 'http:' ? 'ws' : 'wss'
}

export function addMessageListener(callback: ActionCallback) {
eventCallbacks.push(callback)
}
Expand Down Expand Up @@ -62,17 +52,7 @@ export function connectHMR(options: { path: string; assetPrefix: string }) {
timer = setTimeout(init, reconnections > 5 ? 5000 : 1000)
}

const { hostname, port } = location
const protocol = getSocketProtocol(options.assetPrefix || '')
const assetPrefix = options.assetPrefix.replace(/^\/+/, '')

let url = `${protocol}://${hostname}:${port}${
assetPrefix ? `/${assetPrefix}` : ''
}`

if (assetPrefix.startsWith('http')) {
url = `${protocol}://${assetPrefix.split('://', 2)[1]}`
}
const url = getSocketUrl(options.assetPrefix)

source = new window.WebSocket(`${url}${options.path}`)
source.onopen = handleOnline
Expand Down
9 changes: 8 additions & 1 deletion packages/next/src/server/lib/router-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
HMR_ACTIONS_SENT_TO_BROWSER,
type AppIsrManifestAction,
} from '../dev/hot-reloader-types'
import { normalizedAssetPrefix } from '../../shared/lib/normalized-asset-prefix'

const debug = setupDebug('next:router-server:main')
const isNextFont = (pathname: string | null) =>
Expand Down Expand Up @@ -662,8 +663,14 @@ export async function initialize(opts: {
if (opts.dev && developmentBundler && req.url) {
const { basePath, assetPrefix } = config

let hmrPrefix = basePath

// assetPrefix overrides basePath for HMR path
if (assetPrefix) {
ijjk marked this conversation as resolved.
Show resolved Hide resolved
hmrPrefix = normalizedAssetPrefix(assetPrefix)
}
const isHMRRequest = req.url.startsWith(
ensureLeadingSlash(`${assetPrefix || basePath}/_next/webpack-hmr`)
ensureLeadingSlash(`${hmrPrefix}/_next/webpack-hmr`)
)

// only handle HMR requests if the basePath in the request
Expand Down
16 changes: 16 additions & 0 deletions packages/next/src/shared/lib/normalized-asset-prefix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function normalizedAssetPrefix(assetPrefix: string | undefined): string {
const escapedAssetPrefix = assetPrefix?.replace(/^\/+/, '') || false

// assetPrefix as a url
if (escapedAssetPrefix && escapedAssetPrefix.startsWith('://')) {
return escapedAssetPrefix.split('://', 2)[1]
}

// assetPrefix is set to `undefined` or '/'
if (!escapedAssetPrefix) {
return ''
}

// assetPrefix is a common path but escaped so let's add one leading slash
return `/${escapedAssetPrefix}`
}
Loading
Loading