Skip to content

Commit e3c9073

Browse files
authored
base64-encode binary responses (#5048)
* base64-encode binary responses - closes #4174 * tweak comments
1 parent 948c980 commit e3c9073

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

.changeset/lovely-flies-care.md

+5
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

+26-7
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,32 @@ 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

25-
// TODO this is probably wrong now?
26-
if (rendered.body instanceof Uint8Array) {
25+
if (!is_text(response.headers.get('content-type'))) {
2726
// Function responses should be strings (or undefined), and responses with binary
2827
// content should be base64 encoded and set isBase64Encoded to true.
2928
// https://github.com/netlify/functions/blob/main/src/function/response.ts
3029
return {
3130
...partial_response,
3231
isBase64Encoded: true,
33-
body: Buffer.from(rendered.body).toString('base64')
32+
body: Buffer.from(await response.arrayBuffer()).toString('base64')
3433
};
3534
}
3635

3736
return {
3837
...partial_response,
39-
body: await rendered.text()
38+
body: await response.text()
4039
};
4140
};
4241
}
@@ -61,3 +60,23 @@ function to_request(event) {
6160

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

packages/kit/src/runtime/server/endpoint.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const text_types = new Set([
2222
]);
2323

2424
/**
25-
* Decides how the body should be parsed based on its mime type. Should match what's in parse_body
25+
* Decides how the body should be parsed based on its mime type
2626
*
2727
* @param {string | undefined | null} content_type The `content-type` header of a request/response.
2828
* @returns {boolean}

0 commit comments

Comments
 (0)