From f3d5fc98522f273b1512eed64a69cc1802279519 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:02:56 -0300 Subject: [PATCH 01/19] allow binary bodies with any content type --- packages/kit/src/runtime/server/endpoint.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 155e81c182f0..1d2ae5c1f13e 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -38,23 +38,15 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - // validation - if (type === 'application/octet-stream' && !(body instanceof Uint8Array)) { - return error( - `Invalid response from route ${request.path}: body must be an instance of Uint8Array if content type is application/octet-stream` - ); - } - - if (body instanceof Uint8Array && type !== 'application/octet-stream') { - return error( - `Invalid response from route ${request.path}: Uint8Array body must be accompanied by content-type: application/octet-stream header` - ); - } - /** @type {import('types/hooks').StrictBody} */ let normalized_body; - if (typeof body === 'object' && (!type || type === 'application/json')) { + // ensure the body is an object + if ( + typeof body === 'object' && + !(body instanceof Uint8Array) && + (!type || type === 'application/json') + ) { headers = { ...headers, 'content-type': 'application/json' }; normalized_body = JSON.stringify(body); } else { From 2d30a883a8a23c231202aab21d920fc61d3cc679 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 20 Jun 2021 14:42:19 -0300 Subject: [PATCH 02/19] add checks for common binary request bodies --- packages/adapter-cloudflare-workers/files/entry.js | 8 ++++++-- packages/adapter-netlify/files/entry.js | 6 +++++- packages/kit/src/core/node/index.js | 7 ++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index d5749d7f83cb..1e81da6b057e 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -55,9 +55,13 @@ async function handle(event) { /** @param {Request} request */ async function read(request) { const type = request.headers.get('content-type') || ''; - if (type.includes('application/octet-stream')) { + if ( + type.startsWith('image') || + type.startsWith('audio') || + type.startsWith('video') || + type.includes('application/octet-stream') + ) { return new Uint8Array(await request.arrayBuffer()); } - return request.text(); } diff --git a/packages/adapter-netlify/files/entry.js b/packages/adapter-netlify/files/entry.js index c230c41d488a..9d1b79846054 100644 --- a/packages/adapter-netlify/files/entry.js +++ b/packages/adapter-netlify/files/entry.js @@ -8,8 +8,12 @@ export async function handler(event) { const query = new URLSearchParams(rawQuery); + const type = headers['content-type']; const rawBody = - headers['content-type'] === 'application/octet-stream' + type.startsWith('image') || + type.startsWith('audio') || + type.startsWith('video') || + type.includes('application/octet-stream') ? new TextEncoder('base64').encode(body) : isBase64Encoded ? Buffer.from(body, 'base64').toString() diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 7f8e0a57012d..2f3202b3f011 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -48,7 +48,12 @@ export function getRawBody(req) { req.on('end', () => { const [type] = h['content-type'].split(/;\s*/); - if (type === 'application/octet-stream') { + if ( + type.startsWith('image') || + type.startsWith('audio') || + type.startsWith('video') || + type.includes('application/octet-stream') + ) { return fulfil(data); } From 3cd030d87606e32ce33bd7973439807405aaa973 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Tue, 22 Jun 2021 11:42:55 -0300 Subject: [PATCH 03/19] add validation for allowed types --- packages/kit/src/runtime/server/endpoint.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 1d2ae5c1f13e..a9d3b9ca1100 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -38,9 +38,27 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; + const is_type_binary = + type.startsWith('image') || + type.startsWith('audio') || + type.startsWith('video') || + type.includes('application/octet-stream'); /** @type {import('types/hooks').StrictBody} */ let normalized_body; + // validation + if (is_type_binary && !(body instanceof Uint8Array)) { + return error( + `Invalid response from route ${request.path}: body must be an instance of Uint8Array if content type is image/*, audio/*, video/* or application/octet-stream ` + ); + } + + if (body instanceof Uint8Array && !is_type_binary) { + return error( + `Invalid response from route ${request.path}: Uint8Array body must have content-type header of image/*, audio/*, video/* or application/octet-stream` + ); + } + // ensure the body is an object if ( typeof body === 'object' && From 82ef1868ad59ab17c898483382410a0b6f0c9282 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:35:45 -0300 Subject: [PATCH 04/19] add function to get the body type --- packages/kit/src/core/utils.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index d80f38e89f9f..2c5014eaba65 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -106,3 +106,20 @@ function find_svelte_packages(cwd) { export function get_no_external(cwd, user_specified_deps = []) { return [...user_specified_deps, ...find_svelte_packages(cwd)]; } + +/** + * Decides how the body should be parsed based on its mime type. + * + * This is intended to be used with both requests and responses, to have a consistent body parsing across adapters. + * + * @param {string} content_type The `content-type` header of a request/response. + * @returns {"string"|"buffer"} + */ +export function get_body_type(content_type) { + return content_type.startsWith('image') || + content_type.startsWith('audio') || + content_type.startsWith('video') || + content_type.startsWith('application/octet-stream') + ? 'buffer' + : 'string'; +} From dc70750798cf443f5575492acb782d41461c2b55 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:36:06 -0300 Subject: [PATCH 05/19] expose utils file to adapters --- packages/kit/package.json | 3 +++ packages/kit/rollup.config.js | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/kit/package.json b/packages/kit/package.json index c9b4af2b3182..768e2bcec929 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -74,6 +74,9 @@ "./install-fetch": { "import": "./dist/install-fetch.js" }, + "./utils": { + "import": "./dist/utils.js" + }, "./types": "./types/index.d.ts" }, "types": "types/index.d.ts", diff --git a/packages/kit/rollup.config.js b/packages/kit/rollup.config.js index 2abdbec70ff5..d048eb1a069b 100644 --- a/packages/kit/rollup.config.js +++ b/packages/kit/rollup.config.js @@ -48,7 +48,8 @@ export default [ cli: 'src/cli.js', ssr: 'src/runtime/server/index.js', node: 'src/core/node/index.js', - 'install-fetch': 'src/install-fetch.js' + 'install-fetch': 'src/install-fetch.js', + utils: 'src/core/utils.js' }, output: { dir: 'dist', From 3ec5fdde9d1eb3febc8b49d8c50da33cc0dbc46a Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:39:18 -0300 Subject: [PATCH 06/19] replace repeated checks by the utils function --- packages/adapter-cloudflare-workers/files/entry.js | 8 ++------ packages/adapter-netlify/files/entry.js | 6 ++---- packages/kit/src/core/node/index.js | 9 +++------ packages/kit/src/runtime/server/endpoint.js | 7 ++----- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index 001babb2c229..f09666ff53f8 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -1,6 +1,7 @@ // TODO hardcoding the relative location makes this brittle import { init, render } from '../output/server/app.js'; // eslint-disable-line import/no-unresolved import { getAssetFromKV, NotFoundError } from '@cloudflare/kv-asset-handler'; // eslint-disable-line import/no-unresolved +import { get_body_type } from '@sveltejs/kit/utils'; // eslint-disable-line import/no-unresolved init(); @@ -57,12 +58,7 @@ async function handle(event) { /** @param {Request} request */ async function read(request) { const type = request.headers.get('content-type') || ''; - if ( - type.startsWith('image') || - type.startsWith('audio') || - type.startsWith('video') || - type.includes('application/octet-stream') - ) { + if (get_body_type(type) === 'buffer') { return new Uint8Array(await request.arrayBuffer()); } return request.text(); diff --git a/packages/adapter-netlify/files/entry.js b/packages/adapter-netlify/files/entry.js index b2bf8de3ea9d..868967b9ad11 100644 --- a/packages/adapter-netlify/files/entry.js +++ b/packages/adapter-netlify/files/entry.js @@ -1,5 +1,6 @@ // TODO hardcoding the relative location makes this brittle import { init, render } from '../output/server/app.js'; // eslint-disable-line import/no-unresolved +import { get_body_type } from '@sveltejs/kit/utils'; // eslint-disable-line import/no-unresolved init(); @@ -10,10 +11,7 @@ export async function handler(event) { const type = headers['content-type']; const rawBody = - type.startsWith('image') || - type.startsWith('audio') || - type.startsWith('video') || - type.includes('application/octet-stream') + get_body_type(type) === 'buffer' ? new TextEncoder('base64').encode(body) : isBase64Encoded ? Buffer.from(body, 'base64').toString() diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 2f3202b3f011..4e98e4f0c254 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -1,3 +1,5 @@ +import { get_body_type } from '../utils'; + /** * @param {import('http').IncomingMessage} req * @returns {Promise} @@ -48,12 +50,7 @@ export function getRawBody(req) { req.on('end', () => { const [type] = h['content-type'].split(/;\s*/); - if ( - type.startsWith('image') || - type.startsWith('audio') || - type.startsWith('video') || - type.includes('application/octet-stream') - ) { + if (get_body_type(type) === 'buffer') { return fulfil(data); } diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index fd1d1c1f9162..f665c54be2a3 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -1,3 +1,4 @@ +import { get_body_type } from '../../core/utils.js'; import { lowercase_keys } from './utils.js'; /** @param {string} body */ @@ -37,11 +38,7 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - const is_type_binary = - type.startsWith('image') || - type.startsWith('audio') || - type.startsWith('video') || - type.includes('application/octet-stream'); + const is_type_binary = get_body_type(type) === 'buffer'; /** @type {import('types/hooks').StrictBody} */ let normalized_body; From 1ac70ca329aae607afa3f737f6bb9075a898484c Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:44:19 -0300 Subject: [PATCH 07/19] fix import --- packages/kit/src/core/node/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 4e98e4f0c254..71c9e83bcd09 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -1,4 +1,4 @@ -import { get_body_type } from '../utils'; +import { get_body_type } from '../utils.js'; /** * @param {import('http').IncomingMessage} req From f6e2a242f22d92fb816e58f95e5c9467bf925a90 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:53:08 -0300 Subject: [PATCH 08/19] rename function to `isContentTypeBinary` --- packages/kit/src/core/node/index.js | 4 ++-- packages/kit/src/core/utils.js | 2 +- packages/kit/src/runtime/server/endpoint.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 71c9e83bcd09..7e195c133a8a 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -1,4 +1,4 @@ -import { get_body_type } from '../utils.js'; +import { isContentTypeBinary } from '../utils.js'; /** * @param {import('http').IncomingMessage} req @@ -50,7 +50,7 @@ export function getRawBody(req) { req.on('end', () => { const [type] = h['content-type'].split(/;\s*/); - if (get_body_type(type) === 'buffer') { + if (isContentTypeBinary(type) === 'buffer') { return fulfil(data); } diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index 2c5014eaba65..aea5f0473123 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -115,7 +115,7 @@ export function get_no_external(cwd, user_specified_deps = []) { * @param {string} content_type The `content-type` header of a request/response. * @returns {"string"|"buffer"} */ -export function get_body_type(content_type) { +export function isContentTypeBinary(content_type) { return content_type.startsWith('image') || content_type.startsWith('audio') || content_type.startsWith('video') || diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index f665c54be2a3..17b8707bacce 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -1,4 +1,4 @@ -import { get_body_type } from '../../core/utils.js'; +import { isContentTypeBinary } from '../../core/utils.js'; import { lowercase_keys } from './utils.js'; /** @param {string} body */ @@ -38,7 +38,7 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - const is_type_binary = get_body_type(type) === 'buffer'; + const is_type_binary = isContentTypeBinary(type) === 'buffer'; /** @type {import('types/hooks').StrictBody} */ let normalized_body; From 41c60d8b949fe75815d342899d62491903a6b0b1 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:54:45 -0300 Subject: [PATCH 09/19] return a boolean instead of a string enum --- packages/kit/src/core/node/index.js | 2 +- packages/kit/src/core/utils.js | 8 ++++---- packages/kit/src/runtime/server/endpoint.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 7e195c133a8a..3c33541d4658 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -50,7 +50,7 @@ export function getRawBody(req) { req.on('end', () => { const [type] = h['content-type'].split(/;\s*/); - if (isContentTypeBinary(type) === 'buffer') { + if (isContentTypeBinary(type)) { return fulfil(data); } diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index aea5f0473123..7e07cbc3f3d1 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -113,13 +113,13 @@ export function get_no_external(cwd, user_specified_deps = []) { * This is intended to be used with both requests and responses, to have a consistent body parsing across adapters. * * @param {string} content_type The `content-type` header of a request/response. - * @returns {"string"|"buffer"} + * @returns {boolean} */ export function isContentTypeBinary(content_type) { - return content_type.startsWith('image') || + return ( + content_type.startsWith('image') || content_type.startsWith('audio') || content_type.startsWith('video') || content_type.startsWith('application/octet-stream') - ? 'buffer' - : 'string'; + ); } diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 17b8707bacce..8801332802b6 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -38,7 +38,7 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - const is_type_binary = isContentTypeBinary(type) === 'buffer'; + const is_type_binary = isContentTypeBinary(type); /** @type {import('types/hooks').StrictBody} */ let normalized_body; From 304e4d360077424c2f5d907441b1943f9f8a3682 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 17:59:26 -0300 Subject: [PATCH 10/19] move function to `adapter-utils.js` --- packages/kit/package.json | 4 ++-- packages/kit/rollup.config.js | 2 +- packages/kit/src/core/adapter-utils.js | 17 +++++++++++++++++ packages/kit/src/core/node/index.js | 2 +- packages/kit/src/core/utils.js | 17 ----------------- packages/kit/src/runtime/server/endpoint.js | 2 +- 6 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 packages/kit/src/core/adapter-utils.js diff --git a/packages/kit/package.json b/packages/kit/package.json index 768e2bcec929..dc15460bae37 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -74,8 +74,8 @@ "./install-fetch": { "import": "./dist/install-fetch.js" }, - "./utils": { - "import": "./dist/utils.js" + "./adapter-utils": { + "import": "./dist/adapter-utils.js" }, "./types": "./types/index.d.ts" }, diff --git a/packages/kit/rollup.config.js b/packages/kit/rollup.config.js index d048eb1a069b..a24a103f267c 100644 --- a/packages/kit/rollup.config.js +++ b/packages/kit/rollup.config.js @@ -49,7 +49,7 @@ export default [ ssr: 'src/runtime/server/index.js', node: 'src/core/node/index.js', 'install-fetch': 'src/install-fetch.js', - utils: 'src/core/utils.js' + 'adapter-utils': 'src/core/adapter-utils.js' }, output: { dir: 'dist', diff --git a/packages/kit/src/core/adapter-utils.js b/packages/kit/src/core/adapter-utils.js new file mode 100644 index 000000000000..a21b7c60f757 --- /dev/null +++ b/packages/kit/src/core/adapter-utils.js @@ -0,0 +1,17 @@ +/** + * Decides how the body should be parsed based on its mime type. + * + * This is intended to be used with both requests and responses, to have a consistent body parsing across adapters. + * + * @param {string} content_type The `content-type` header of a request/response. + * @returns {boolean} + */ + +export function isContentTypeBinary(content_type) { + return ( + content_type.startsWith('image') || + content_type.startsWith('audio') || + content_type.startsWith('video') || + content_type.startsWith('application/octet-stream') + ); +} diff --git a/packages/kit/src/core/node/index.js b/packages/kit/src/core/node/index.js index 3c33541d4658..451268a6cba7 100644 --- a/packages/kit/src/core/node/index.js +++ b/packages/kit/src/core/node/index.js @@ -1,4 +1,4 @@ -import { isContentTypeBinary } from '../utils.js'; +import { isContentTypeBinary } from '../adapter-utils.js'; /** * @param {import('http').IncomingMessage} req diff --git a/packages/kit/src/core/utils.js b/packages/kit/src/core/utils.js index 7e07cbc3f3d1..d80f38e89f9f 100644 --- a/packages/kit/src/core/utils.js +++ b/packages/kit/src/core/utils.js @@ -106,20 +106,3 @@ function find_svelte_packages(cwd) { export function get_no_external(cwd, user_specified_deps = []) { return [...user_specified_deps, ...find_svelte_packages(cwd)]; } - -/** - * Decides how the body should be parsed based on its mime type. - * - * This is intended to be used with both requests and responses, to have a consistent body parsing across adapters. - * - * @param {string} content_type The `content-type` header of a request/response. - * @returns {boolean} - */ -export function isContentTypeBinary(content_type) { - return ( - content_type.startsWith('image') || - content_type.startsWith('audio') || - content_type.startsWith('video') || - content_type.startsWith('application/octet-stream') - ); -} diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 8801332802b6..4c6bfbce7ea5 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -1,4 +1,4 @@ -import { isContentTypeBinary } from '../../core/utils.js'; +import { isContentTypeBinary } from '../../core/adapter-utils.js'; import { lowercase_keys } from './utils.js'; /** @param {string} body */ From 27ac1c58112afc71e52d2c5ca38c069a377b6bb3 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 18:18:53 -0300 Subject: [PATCH 11/19] update adapters --- packages/adapter-cloudflare-workers/files/entry.js | 4 ++-- packages/adapter-netlify/files/entry.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index f09666ff53f8..5bfbbf073c41 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -1,7 +1,7 @@ // TODO hardcoding the relative location makes this brittle import { init, render } from '../output/server/app.js'; // eslint-disable-line import/no-unresolved import { getAssetFromKV, NotFoundError } from '@cloudflare/kv-asset-handler'; // eslint-disable-line import/no-unresolved -import { get_body_type } from '@sveltejs/kit/utils'; // eslint-disable-line import/no-unresolved +import { isContentTypeBinary } from '@sveltejs/kit/adapter-utils'; // eslint-disable-line import/no-unresolved init(); @@ -58,7 +58,7 @@ async function handle(event) { /** @param {Request} request */ async function read(request) { const type = request.headers.get('content-type') || ''; - if (get_body_type(type) === 'buffer') { + if (isContentTypeBinary(type) === 'buffer') { return new Uint8Array(await request.arrayBuffer()); } return request.text(); diff --git a/packages/adapter-netlify/files/entry.js b/packages/adapter-netlify/files/entry.js index 868967b9ad11..2fa8209f11d4 100644 --- a/packages/adapter-netlify/files/entry.js +++ b/packages/adapter-netlify/files/entry.js @@ -1,6 +1,6 @@ // TODO hardcoding the relative location makes this brittle import { init, render } from '../output/server/app.js'; // eslint-disable-line import/no-unresolved -import { get_body_type } from '@sveltejs/kit/utils'; // eslint-disable-line import/no-unresolved +import { isContentTypeBinary } from '@sveltejs/kit/adapter-utils'; // eslint-disable-line import/no-unresolved init(); @@ -11,7 +11,7 @@ export async function handler(event) { const type = headers['content-type']; const rawBody = - get_body_type(type) === 'buffer' + isContentTypeBinary(type) === 'buffer' ? new TextEncoder('base64').encode(body) : isBase64Encoded ? Buffer.from(body, 'base64').toString() From 819ba9500ba070f20f5bc3d578c94cb0bb8bfc75 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 18:38:09 -0300 Subject: [PATCH 12/19] fix issues --- packages/adapter-cloudflare-workers/files/entry.js | 2 +- packages/adapter-netlify/files/entry.js | 11 +++++------ packages/kit/src/core/adapter-utils.js | 1 - packages/kit/src/runtime/server/endpoint.js | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index 5bfbbf073c41..1310dbc7dada 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -58,7 +58,7 @@ async function handle(event) { /** @param {Request} request */ async function read(request) { const type = request.headers.get('content-type') || ''; - if (isContentTypeBinary(type) === 'buffer') { + if (isContentTypeBinary(type)) { return new Uint8Array(await request.arrayBuffer()); } return request.text(); diff --git a/packages/adapter-netlify/files/entry.js b/packages/adapter-netlify/files/entry.js index 2fa8209f11d4..5dd6fbfc98f7 100644 --- a/packages/adapter-netlify/files/entry.js +++ b/packages/adapter-netlify/files/entry.js @@ -10,12 +10,11 @@ export async function handler(event) { const query = new URLSearchParams(rawQuery); const type = headers['content-type']; - const rawBody = - isContentTypeBinary(type) === 'buffer' - ? new TextEncoder('base64').encode(body) - : isBase64Encoded - ? Buffer.from(body, 'base64').toString() - : body; + const rawBody = isContentTypeBinary(type) + ? new TextEncoder('base64').encode(body) + : isBase64Encoded + ? Buffer.from(body, 'base64').toString() + : body; const rendered = await render({ method: httpMethod, diff --git a/packages/kit/src/core/adapter-utils.js b/packages/kit/src/core/adapter-utils.js index a21b7c60f757..8ebead033098 100644 --- a/packages/kit/src/core/adapter-utils.js +++ b/packages/kit/src/core/adapter-utils.js @@ -6,7 +6,6 @@ * @param {string} content_type The `content-type` header of a request/response. * @returns {boolean} */ - export function isContentTypeBinary(content_type) { return ( content_type.startsWith('image') || diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 4c6bfbce7ea5..22206625d8c7 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -38,9 +38,9 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - const is_type_binary = isContentTypeBinary(type); /** @type {import('types/hooks').StrictBody} */ let normalized_body; + const is_type_binary = isContentTypeBinary(type); // validation if (is_type_binary && !(body instanceof Uint8Array)) { From 9e79f750c08933e55cefb4f1e9a1cdf4f9f2b702 Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 19:00:50 -0300 Subject: [PATCH 13/19] handle undefined content type --- packages/adapter-netlify/files/entry.js | 11 ++++++----- packages/kit/src/runtime/server/endpoint.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/adapter-netlify/files/entry.js b/packages/adapter-netlify/files/entry.js index 5dd6fbfc98f7..cd920d418b3a 100644 --- a/packages/adapter-netlify/files/entry.js +++ b/packages/adapter-netlify/files/entry.js @@ -10,11 +10,12 @@ export async function handler(event) { const query = new URLSearchParams(rawQuery); const type = headers['content-type']; - const rawBody = isContentTypeBinary(type) - ? new TextEncoder('base64').encode(body) - : isBase64Encoded - ? Buffer.from(body, 'base64').toString() - : body; + const rawBody = + type && isContentTypeBinary(type) + ? new TextEncoder('base64').encode(body) + : isBase64Encoded + ? Buffer.from(body, 'base64').toString() + : body; const rendered = await render({ method: httpMethod, diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 22206625d8c7..145a61177761 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -40,7 +40,7 @@ export default async function render_route(request, route) { /** @type {import('types/hooks').StrictBody} */ let normalized_body; - const is_type_binary = isContentTypeBinary(type); + const is_type_binary = type && isContentTypeBinary(type); // validation if (is_type_binary && !(body instanceof Uint8Array)) { From 6562f173fc1fe9a77ff901dce41abdd85747f89c Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 20:37:31 -0300 Subject: [PATCH 14/19] add changeset --- .changeset/great-guests-visit.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/great-guests-visit.md diff --git a/.changeset/great-guests-visit.md b/.changeset/great-guests-visit.md new file mode 100644 index 000000000000..3f8001aaffe6 --- /dev/null +++ b/.changeset/great-guests-visit.md @@ -0,0 +1,7 @@ +--- +'@sveltejs/adapter-cloudflare-workers': patch +'@sveltejs/adapter-netlify': patch +'@sveltejs/kit': patch +--- + +Update and consolidate checks for binary body types From 949bcb186b717b60ba5a72a56ef4fc21e1bb261e Mon Sep 17 00:00:00 2001 From: JeanJPNM <61994401+JeanJPNM@users.noreply.github.com> Date: Sun, 11 Jul 2021 21:19:28 -0300 Subject: [PATCH 15/19] small style changes --- packages/adapter-cloudflare-workers/files/entry.js | 1 + packages/kit/src/runtime/server/endpoint.js | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/adapter-cloudflare-workers/files/entry.js b/packages/adapter-cloudflare-workers/files/entry.js index 1310dbc7dada..5b5dde625d0d 100644 --- a/packages/adapter-cloudflare-workers/files/entry.js +++ b/packages/adapter-cloudflare-workers/files/entry.js @@ -61,5 +61,6 @@ async function read(request) { if (isContentTypeBinary(type)) { return new Uint8Array(await request.arrayBuffer()); } + return request.text(); } diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index 145a61177761..a24bc43c2548 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -38,8 +38,6 @@ export default async function render_route(request, route) { headers = lowercase_keys(headers); const type = headers['content-type']; - /** @type {import('types/hooks').StrictBody} */ - let normalized_body; const is_type_binary = type && isContentTypeBinary(type); // validation @@ -55,6 +53,9 @@ export default async function render_route(request, route) { ); } + /** @type {import('types/hooks').StrictBody} */ + let normalized_body; + // ensure the body is an object if ( (typeof body === 'object' || typeof body === 'undefined') && From a8b4cbf2e00a42e5213db0c1f70f022137faee89 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sun, 11 Jul 2021 20:37:22 -0700 Subject: [PATCH 16/19] Update packages/kit/src/runtime/server/endpoint.js --- packages/kit/src/runtime/server/endpoint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index a24bc43c2548..94c232a47bca 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -43,7 +43,7 @@ export default async function render_route(request, route) { // validation if (is_type_binary && !(body instanceof Uint8Array)) { return error( - `${preface}: body must be an instance of Uint8Array if content type is image/*, audio/*, video/* or application/octet-stream ` + `${preface}: body must be an instance of Uint8Array if content type is image/*, audio/*, video/* or application/octet-stream` ); } From 084d26b002bb67de2873ac7196e4f6e0f1d4c4a9 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sun, 11 Jul 2021 20:42:38 -0700 Subject: [PATCH 17/19] Update packages/kit/src/core/adapter-utils.js --- packages/kit/src/core/adapter-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/core/adapter-utils.js b/packages/kit/src/core/adapter-utils.js index 8ebead033098..9eb1d9e3b749 100644 --- a/packages/kit/src/core/adapter-utils.js +++ b/packages/kit/src/core/adapter-utils.js @@ -8,7 +8,7 @@ */ export function isContentTypeBinary(content_type) { return ( - content_type.startsWith('image') || + content_type.startsWith('image/') || content_type.startsWith('audio') || content_type.startsWith('video') || content_type.startsWith('application/octet-stream') From 01414fb1eab1de7949f2f45b1031b16b27d0b715 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sun, 11 Jul 2021 20:42:52 -0700 Subject: [PATCH 18/19] Update packages/kit/src/core/adapter-utils.js --- packages/kit/src/core/adapter-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/core/adapter-utils.js b/packages/kit/src/core/adapter-utils.js index 9eb1d9e3b749..8aab9d926f5a 100644 --- a/packages/kit/src/core/adapter-utils.js +++ b/packages/kit/src/core/adapter-utils.js @@ -9,7 +9,7 @@ export function isContentTypeBinary(content_type) { return ( content_type.startsWith('image/') || - content_type.startsWith('audio') || + content_type.startsWith('audio/') || content_type.startsWith('video') || content_type.startsWith('application/octet-stream') ); From e4fac6ddb81ab21d1cd5c74dc569ad95a5a19d19 Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Sun, 11 Jul 2021 20:43:07 -0700 Subject: [PATCH 19/19] Update packages/kit/src/core/adapter-utils.js --- packages/kit/src/core/adapter-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/core/adapter-utils.js b/packages/kit/src/core/adapter-utils.js index 8aab9d926f5a..192a962ff57c 100644 --- a/packages/kit/src/core/adapter-utils.js +++ b/packages/kit/src/core/adapter-utils.js @@ -10,7 +10,7 @@ export function isContentTypeBinary(content_type) { return ( content_type.startsWith('image/') || content_type.startsWith('audio/') || - content_type.startsWith('video') || + content_type.startsWith('video/') || content_type.startsWith('application/octet-stream') ); }