From 2b63578a84357fef045aa2db09e03d4ae308b7cd Mon Sep 17 00:00:00 2001 From: Ahad Birang Date: Mon, 20 Sep 2021 22:42:43 +0430 Subject: [PATCH] feat(nitro): handle request body in workers (#537) --- .../nitro/src/runtime/entries/cloudflare.ts | 5 ++++ .../src/runtime/entries/service-worker.ts | 7 ++--- packages/nitro/src/runtime/server/utils.ts | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 packages/nitro/src/runtime/server/utils.ts diff --git a/packages/nitro/src/runtime/entries/cloudflare.ts b/packages/nitro/src/runtime/entries/cloudflare.ts index 2f5fddbeb0..8dfa681d74 100644 --- a/packages/nitro/src/runtime/entries/cloudflare.ts +++ b/packages/nitro/src/runtime/entries/cloudflare.ts @@ -1,6 +1,7 @@ import '#polyfill' import { getAssetFromKV } from '@cloudflare/kv-asset-handler' import { localCall } from '../server' +import { requestHasBody, useRequestBody } from '../server/utils' const PUBLIC_PATH = process.env.PUBLIC_PATH // Default: /_nuxt/ @@ -17,6 +18,10 @@ async function handleEvent (event) { const url = new URL(event.request.url) + if (requestHasBody(event.request)) { + event.request.body = await useRequestBody(event.request) + } + const r = await localCall({ event, url: url.pathname + url.search, diff --git a/packages/nitro/src/runtime/entries/service-worker.ts b/packages/nitro/src/runtime/entries/service-worker.ts index 06e0ae8526..d0411ee2cc 100644 --- a/packages/nitro/src/runtime/entries/service-worker.ts +++ b/packages/nitro/src/runtime/entries/service-worker.ts @@ -1,9 +1,9 @@ // @ts-nocheck import '#polyfill' import { localCall } from '../server' +import { requestHasBody, useRequestBody } from '../server/utils' const STATIC_ASSETS_BASE = process.env.NUXT_STATIC_BASE + '/' + process.env.NUXT_STATIC_VERSION -const METHODS_WITH_BODY = ['POST', 'PUT', 'PATCH'] addEventListener('fetch', (event: any) => { const url = new URL(event.request.url) @@ -16,9 +16,10 @@ addEventListener('fetch', (event: any) => { }) async function handleEvent (url, event) { - if (METHODS_WITH_BODY.includes(event.request.method.toUpperCase()) && !event.request.body) { - event.request.body = await event.request.text() + if (requestHasBody(event.request)) { + event.request.body = await useRequestBody(event.request) } + const r = await localCall({ event, url: url.pathname + url.search, diff --git a/packages/nitro/src/runtime/server/utils.ts b/packages/nitro/src/runtime/server/utils.ts new file mode 100644 index 0000000000..88835b293d --- /dev/null +++ b/packages/nitro/src/runtime/server/utils.ts @@ -0,0 +1,26 @@ +const METHOD_WITH_BODY_RE = /post|put|patch/i +const TEXT_MIME_RE = /application\/text|text\/html/ +const JSON_MIME_RE = /application\/json/ + +export function requestHasBody (request: globalThis.Request) : boolean { + return METHOD_WITH_BODY_RE.test(request.method) +} + +export async function useRequestBody (request: globalThis.Request): Promise { + const contentType = request.headers.get('content-type') || '' + if (contentType.includes('form')) { + const formData = await request.formData() + const body = Object.create(null) + for (const entry of formData.entries()) { + body[entry[0]] = entry[1] + } + return body + } else if (JSON_MIME_RE.test(contentType)) { + return request.json() + } else if (TEXT_MIME_RE.test(contentType)) { + return request.text() + } else { + const blob = await request.blob() + return URL.createObjectURL(blob) + } +}