0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-23 21:53:55 -05:00

Fix for Node SSR with Express JSON middleware fails on POST (#6192)

* Fix for Node SSR with Express JSON middleware fails on POST

* Removed the unwanted setting of the req property

* Removed the unwanted setting of the req property

* Removed the unwanted setting of the req property

* Fixed the if statement to not break the existing logic and unit test

* Cleaned up the if statement

* Changed to better solution from Geoffrey-Pliez

* Added class NodeIncomingMessage with body defined as any

---------

Co-authored-by: Matthew Phillips <matthew@skypack.dev>
This commit is contained in:
Eric R Glass 2023-03-24 11:30:47 -04:00 committed by GitHub
parent b558bd5140
commit b7194103e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 4 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Updated to fix the Node SSR fails on POST with Express JSON middleware

View file

@ -9,7 +9,7 @@ import { App, type MatchOptions } from './index.js';
const clientAddressSymbol = Symbol.for('astro.clientAddress'); const clientAddressSymbol = Symbol.for('astro.clientAddress');
function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array): Request { function createRequestFromNodeRequest(req: NodeIncomingMessage, body?: Uint8Array): Request {
const protocol = const protocol =
req.socket instanceof TLSSocket || req.headers['x-forwarded-proto'] === 'https' req.socket instanceof TLSSocket || req.headers['x-forwarded-proto'] === 'https'
? 'https' ? 'https'
@ -29,11 +29,32 @@ function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array):
return request; return request;
} }
class NodeIncomingMessage extends IncomingMessage {
/**
* The read-only body property of the Request interface contains a ReadableStream with the body contents that have been added to the request.
*/
body?: any | undefined;
}
export class NodeApp extends App { export class NodeApp extends App {
match(req: IncomingMessage | Request, opts: MatchOptions = {}) { match(req: NodeIncomingMessage | Request, opts: MatchOptions = {}) {
return super.match(req instanceof Request ? req : createRequestFromNodeRequest(req), opts); return super.match(req instanceof Request ? req : createRequestFromNodeRequest(req), opts);
} }
render(req: IncomingMessage | Request, routeData?: RouteData) { render(req: NodeIncomingMessage | Request, routeData?: RouteData) {
if (typeof (req.body) === 'string' && req.body.length > 0) {
return super.render(
req instanceof Request ? req : createRequestFromNodeRequest(req, Buffer.from(req.body)),
routeData
);
}
if ((typeof (req.body) === 'object') && (Object.keys(req.body).length > 0)) {
return super.render(
req instanceof Request ? req : createRequestFromNodeRequest(req, Buffer.from(JSON.stringify(req.body))),
routeData
);
}
if ('on' in req) { if ('on' in req) {
let body = Buffer.from([]); let body = Buffer.from([]);
let reqBodyComplete = new Promise((resolve, reject) => { let reqBodyComplete = new Promise((resolve, reject) => {
@ -72,4 +93,4 @@ export async function loadManifest(rootFolder: URL): Promise<SSRManifest> {
export async function loadApp(rootFolder: URL): Promise<NodeApp> { export async function loadApp(rootFolder: URL): Promise<NodeApp> {
const manifest = await loadManifest(rootFolder); const manifest = await loadManifest(rootFolder);
return new NodeApp(manifest); return new NodeApp(manifest);
} }