Fixes binary data request bodies in the Node adapter (#4055)
* Fixes binary data request bodies in the Node adapter * Fix type
This commit is contained in:
parent
00768580af
commit
44694d8a90
4 changed files with 36 additions and 10 deletions
6
.changeset/slow-terms-repeat.md
Normal file
6
.changeset/slow-terms-repeat.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
'@astrojs/node': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Handle binary data request bodies in the Node adapter
|
|
@ -7,7 +7,7 @@ import { App } from './index.js';
|
||||||
|
|
||||||
const clientAddressSymbol = Symbol.for('astro.clientAddress');
|
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 url = `http://${req.headers.host}${req.url}`;
|
||||||
let rawHeaders = req.headers as Record<string, any>;
|
let rawHeaders = req.headers as Record<string, any>;
|
||||||
const entries = Object.entries(rawHeaders);
|
const entries = Object.entries(rawHeaders);
|
||||||
|
@ -28,17 +28,10 @@ export class NodeApp extends App {
|
||||||
}
|
}
|
||||||
render(req: IncomingMessage | Request) {
|
render(req: IncomingMessage | Request) {
|
||||||
if ('on' in req) {
|
if ('on' in req) {
|
||||||
let body: string | undefined = undefined;
|
let body = Buffer.from([]);
|
||||||
let reqBodyComplete = new Promise((resolve, reject) => {
|
let reqBodyComplete = new Promise((resolve, reject) => {
|
||||||
req.on('data', (d) => {
|
req.on('data', (d) => {
|
||||||
if (body === undefined) {
|
body = Buffer.concat([body, d]);
|
||||||
body = '';
|
|
||||||
}
|
|
||||||
if (d instanceof Buffer) {
|
|
||||||
body += d.toString('utf-8');
|
|
||||||
} else if (typeof d === 'string') {
|
|
||||||
body += d;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
req.on('end', () => {
|
req.on('end', () => {
|
||||||
resolve(body);
|
resolve(body);
|
||||||
|
|
|
@ -31,4 +31,20 @@ describe('API routes', () => {
|
||||||
expect(json.length).to.equal(1);
|
expect(json.length).to.equal(1);
|
||||||
expect(json[0].name).to.equal('Broccoli Soup');
|
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]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
11
packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
vendored
Normal file
11
packages/integrations/node/test/fixtures/api-route/src/pages/binary.ts
vendored
Normal file
|
@ -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'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue