Skip to content

Commit

Permalink
Fixes binary data request bodies in the Node adapter (#4055)
Browse files Browse the repository at this point in the history
* Fixes binary data request bodies in the Node adapter

* Fix type
  • Loading branch information
matthewp authored Jul 26, 2022
1 parent 0076858 commit 44694d8
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .changeset/slow-terms-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/node': patch
---

Handle binary data request bodies in the Node adapter
13 changes: 3 additions & 10 deletions packages/astro/src/core/app/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { App } from './index.js';

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

function createRequestFromNodeRequest(req: IncomingMessage, body?: string): Request {
function createRequestFromNodeRequest(req: IncomingMessage, body?: Uint8Array): Request {
let url = `http://${req.headers.host}${req.url}`;
let rawHeaders = req.headers as Record<string, any>;
const entries = Object.entries(rawHeaders);
Expand All @@ -28,17 +28,10 @@ export class NodeApp extends App {
}
render(req: IncomingMessage | Request) {
if ('on' in req) {
let body: string | undefined = undefined;
let body = Buffer.from([]);
let reqBodyComplete = new Promise((resolve, reject) => {
req.on('data', (d) => {
if (body === undefined) {
body = '';
}
if (d instanceof Buffer) {
body += d.toString('utf-8');
} else if (typeof d === 'string') {
body += d;
}
body = Buffer.concat([body, d]);
});
req.on('end', () => {
resolve(body);
Expand Down
16 changes: 16 additions & 0 deletions packages/integrations/node/test/api-route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,20 @@ describe('API routes', () => {
expect(json.length).to.equal(1);
expect(json[0].name).to.equal('Broccoli Soup');
});

it('Can get binary data', async () => {
const { handler } = await import('./fixtures/api-route/dist/server/entry.mjs');

let { req, res, done } = createRequestAndResponse({
method: 'POST',
url: '/binary',
});

handler(req, res);
req.send(Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));

let [out] = await done;
let arr = Array.from(new Uint8Array(out.buffer));
expect(arr).to.deep.equal([5, 4, 3, 2, 1]);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

export async function post({ request }: { request: Request }) {
let body = await request.arrayBuffer();
let data = new Uint8Array(body);
let r = data.reverse();
return new Response(r, {
headers: {
'Content-Type': 'application/octet-stream'
}
});
}

0 comments on commit 44694d8

Please sign in to comment.