Skip to content

Commit

Permalink
base64-encode binary responses (#5048)
Browse files Browse the repository at this point in the history
* base64-encode binary responses - closes #4174

* tweak comments
  • Loading branch information
Rich-Harris authored May 24, 2022
1 parent 948c980 commit e3c9073
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-flies-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-netlify': patch
---

Encode binary responses as base64
33 changes: 26 additions & 7 deletions packages/adapter-netlify/src/serverless.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,32 @@ export function init(manifest) {
const server = new Server(manifest);

return async (event, context) => {
const rendered = await server.respond(to_request(event), {
const response = await server.respond(to_request(event), {
platform: { context },
getClientAddress() {
return event.headers['x-nf-client-connection-ip'];
}
});

const partial_response = {
statusCode: rendered.status,
...split_headers(rendered.headers)
statusCode: response.status,
...split_headers(response.headers)
};

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

return {
...partial_response,
body: await rendered.text()
body: await response.text()
};
};
}
Expand All @@ -61,3 +60,23 @@ function to_request(event) {

return new Request(rawUrl, init);
}

const text_types = new Set([
'application/xml',
'application/json',
'application/x-www-form-urlencoded',
'multipart/form-data'
]);

/**
* Decides how the body should be parsed based on its mime type
*
* @param {string | undefined | null} content_type The `content-type` header of a request/response.
* @returns {boolean}
*/
function is_text(content_type) {
if (!content_type) return true; // defaults to json
const type = content_type.split(';')[0].toLowerCase(); // get the mime type

return type.startsWith('text/') || type.endsWith('+xml') || text_types.has(type);
}
2 changes: 1 addition & 1 deletion packages/kit/src/runtime/server/endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const text_types = new Set([
]);

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

0 comments on commit e3c9073

Please sign in to comment.