summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/slow-terms-repeat.md6
-rw-r--r--packages/astro/src/core/app/node.ts13
-rw-r--r--packages/integrations/node/test/api-route.test.js16
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts11
4 files changed, 36 insertions, 10 deletions
diff --git a/.changeset/slow-terms-repeat.md b/.changeset/slow-terms-repeat.md
new file mode 100644
index 000000000..808556f54
--- /dev/null
+++ b/.changeset/slow-terms-repeat.md
@@ -0,0 +1,6 @@
+---
+'astro': patch
+'@astrojs/node': patch
+---
+
+Handle binary data request bodies in the Node adapter
diff --git a/packages/astro/src/core/app/node.ts b/packages/astro/src/core/app/node.ts
index cb5356f63..c7e6f1eca 100644
--- a/packages/astro/src/core/app/node.ts
+++ b/packages/astro/src/core/app/node.ts
@@ -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);
@@ -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);
diff --git a/packages/integrations/node/test/api-route.test.js b/packages/integrations/node/test/api-route.test.js
index 034b53c07..cd074ef27 100644
--- a/packages/integrations/node/test/api-route.test.js
+++ b/packages/integrations/node/test/api-route.test.js
@@ -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]);
+ });
});
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
new file mode 100644
index 000000000..6b50bc341
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
@@ -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'
+ }
+ });
+}