Skip to content

Commit

Permalink
chore(rsc): Extract RSA handling in rscRequestHandler.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe committed Oct 18, 2024
1 parent 74e785d commit c87b60e
Showing 1 changed file with 62 additions and 49 deletions.
111 changes: 62 additions & 49 deletions packages/vite/src/rsc/rscRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,61 +99,14 @@ export function createRscRequestHandler(
console.log('rscId', rscId)
console.log('rsaId', rsaId)

// TODO (RSC): When is this ever '_'? Can we remove that extra check?
if (rscId && rscId !== '_') {
res.setHeader('Content-Type', 'text/x-component')
} else {
rscId = undefined
}

if (rsaId) {
// TODO (RSC): For React Server Actions we need to limit the request
// size somehow
// https://nextjs.org/docs/app/api-reference/functions/server-actions#size-limitation
if (req.headers['content-type']?.startsWith('multipart/form-data')) {
console.log('RSA: multipart/form-data')
const bb = busboy({ headers: req.headers })
// TODO (RSC): The generic here could be typed better
const reply = decodeReplyFromBusboy<unknown[]>(bb)

req.pipe(bb)
args = await reply

// TODO (RSC): Loop over args (to not only look at args[0])
if (args[0] instanceof FormData) {
const serializedFormData: Record<string, any> = {}

for (const [key, value] of args[0]) {
// Several form fields can share the same name. This should be
// represented as an array of the values of all those fields
if (serializedFormData[key] !== undefined) {
if (!Array.isArray(serializedFormData[key])) {
serializedFormData[key] = [serializedFormData[key]]
}

serializedFormData[key].push(value)
} else {
serializedFormData[key] = value
}
}

args[0] = {
__formData__: true,
state: serializedFormData,
}
}
} else {
console.log('RSA: regular body')
let body = ''

for await (const chunk of req) {
body += chunk
}

if (body) {
args = await decodeReply(body)
}
}
}
args = await handleRsa(rsaId, req, args)
}

console.log('rscRequestHandler: args', args)
Expand Down Expand Up @@ -204,3 +157,63 @@ export function createRscRequestHandler(
}
}
}

async function handleRsa(
rsaId: string | undefined,
req: ExpressRequest,
args: unknown[],
) {
if (!rsaId) {
return args
}

// TODO (RSC): For React Server Actions we need to limit the request
// size somehow
// https://nextjs.org/docs/app/api-reference/functions/server-actions#size-limitation
if (req.headers['content-type']?.startsWith('multipart/form-data')) {
console.log('RSA: multipart/form-data')
const bb = busboy({ headers: req.headers })
// TODO (RSC): The generic here could be typed better
const reply = decodeReplyFromBusboy<unknown[]>(bb)

req.pipe(bb)
args = await reply

// TODO (RSC): Loop over args (to not only look at args[0])
if (args[0] instanceof FormData) {
const serializedFormData: Record<string, any> = {}

for (const [key, value] of args[0]) {
// Several form fields can share the same name. This should be
// represented as an array of the values of all those fields
if (serializedFormData[key] !== undefined) {
if (!Array.isArray(serializedFormData[key])) {
serializedFormData[key] = [serializedFormData[key]]
}

serializedFormData[key].push(value)
} else {
serializedFormData[key] = value
}
}

args[0] = {
__formData__: true,
state: serializedFormData,
}
}
} else {
console.log('RSA: regular body')
let body = ''

for await (const chunk of req) {
body += chunk
}

if (body) {
args = await decodeReply(body)
}
}

return args
}

0 comments on commit c87b60e

Please sign in to comment.