Skip to content

Commit c628558

Browse files
committed
base64-encode binary responses - closes #4174
1 parent 948c980 commit c628558

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

.changeset/lovely-flies-care.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/adapter-netlify': patch
3+
---
4+
5+
Encode binary responses as base64

packages/adapter-netlify/src/serverless.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,33 @@ export function init(manifest) {
1010
const server = new Server(manifest);
1111

1212
return async (event, context) => {
13-
const rendered = await server.respond(to_request(event), {
13+
const response = await server.respond(to_request(event), {
1414
platform: { context },
1515
getClientAddress() {
1616
return event.headers['x-nf-client-connection-ip'];
1717
}
1818
});
1919

2020
const partial_response = {
21-
statusCode: rendered.status,
22-
...split_headers(rendered.headers)
21+
statusCode: response.status,
22+
...split_headers(response.headers)
2323
};
2424

2525
// TODO this is probably wrong now?
26-
if (rendered.body instanceof Uint8Array) {
26+
if (!is_text(response.headers.get('content-type'))) {
2727
// Function responses should be strings (or undefined), and responses with binary
2828
// content should be base64 encoded and set isBase64Encoded to true.
2929
// https://github.com/netlify/functions/blob/main/src/function/response.ts
3030
return {
3131
...partial_response,
3232
isBase64Encoded: true,
33-
body: Buffer.from(rendered.body).toString('base64')
33+
body: Buffer.from(await response.arrayBuffer()).toString('base64')
3434
};
3535
}
3636

3737
return {
3838
...partial_response,
39-
body: await rendered.text()
39+
body: await response.text()
4040
};
4141
};
4242
}
@@ -61,3 +61,23 @@ function to_request(event) {
6161

6262
return new Request(rawUrl, init);
6363
}
64+
65+
const text_types = new Set([
66+
'application/xml',
67+
'application/json',
68+
'application/x-www-form-urlencoded',
69+
'multipart/form-data'
70+
]);
71+
72+
/**
73+
* Decides how the body should be parsed based on its mime type. Should match what's in parse_body
74+
*
75+
* @param {string | undefined | null} content_type The `content-type` header of a request/response.
76+
* @returns {boolean}
77+
*/
78+
function is_text(content_type) {
79+
if (!content_type) return true; // defaults to json
80+
const type = content_type.split(';')[0].toLowerCase(); // get the mime type
81+
82+
return type.startsWith('text/') || type.endsWith('+xml') || text_types.has(type);
83+
}

0 commit comments

Comments
 (0)