Skip to content

Commit

Permalink
Fix for Node SSR with Express JSON middleware fails on POST (withastr…
Browse files Browse the repository at this point in the history
…o#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 <[email protected]>
  • Loading branch information
erg208 and matthewp authored Mar 24, 2023
1 parent b558bd5 commit b719410
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-vans-wonder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Updated to fix the Node SSR fails on POST with Express JSON middleware
29 changes: 25 additions & 4 deletions packages/astro/src/core/app/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { App, type MatchOptions } from './index.js';

const clientAddressSymbol = Symbol.for('astro.clientAddress');

function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array): Request {
function createRequestFromNodeRequest(req: NodeIncomingMessage, body?: Uint8Array): Request {
const protocol =
req.socket instanceof TLSSocket || req.headers['x-forwarded-proto'] === 'https'
? 'https'
Expand All @@ -29,11 +29,32 @@ function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array):
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 {
match(req: IncomingMessage | Request, opts: MatchOptions = {}) {
match(req: NodeIncomingMessage | Request, opts: MatchOptions = {}) {
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) {
let body = Buffer.from([]);
let reqBodyComplete = new Promise((resolve, reject) => {
Expand Down Expand Up @@ -72,4 +93,4 @@ export async function loadManifest(rootFolder: URL): Promise<SSRManifest> {
export async function loadApp(rootFolder: URL): Promise<NodeApp> {
const manifest = await loadManifest(rootFolder);
return new NodeApp(manifest);
}
}

0 comments on commit b719410

Please sign in to comment.