From 1485b25a4bb0ebd224446ed5326131b36d3f3518 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 13 Apr 2022 19:00:03 +0200 Subject: [PATCH] fix: formdata cleanup (#1336) * fix: formdata cleanup * Update lib/core/request.js --- lib/client.js | 24 +----------------------- lib/core/request.js | 26 ++++++++++++++++++++++++-- lib/fetch/body.js | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/client.js b/lib/client.js index 5c1ca952031..d3d4cfc705d 100644 --- a/lib/client.js +++ b/lib/client.js @@ -67,12 +67,6 @@ const { const kClosedResolve = Symbol('kClosedResolve') const channels = {} -const [nodeMajor, nodeMinor] = process.version - .slice(1) // remove 'v' - .split('.', 2) - .map(v => Number(v)) - -let extractBody try { const diagnosticsChannel = require('diagnostics_channel') @@ -1586,26 +1580,10 @@ async function writeIterable ({ body, client, request, socket, contentLength, he .on('close', onDrain) .on('drain', onDrain) - let bodyAsyncIterable = body - - if (util.isFormDataLike(body)) { - if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 5)) { - throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.5 and newer.') - } - - if (!extractBody) { - extractBody = require('./fetch/body.js').extractBody - } - - const [bodyStream, contentType] = extractBody(body) - header += `content-type: ${contentType}\r\n` - bodyAsyncIterable = bodyStream.stream - } - const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) try { // It's up to the user to somehow abort the async iterable. - for await (const chunk of bodyAsyncIterable) { + for await (const chunk of body) { if (socket[kError]) { throw socket[kError] } diff --git a/lib/core/request.js b/lib/core/request.js index 0d98987d9d1..80ff607ca27 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -11,6 +11,13 @@ const kHandler = Symbol('handler') const channels = {} +let extractBody + +const [nodeMajor, nodeMinor] = process.version + .slice(1) // remove 'v' + .split('.', 2) + .map(v => Number(v)) + try { const diagnosticsChannel = require('diagnostics_channel') channels.create = diagnosticsChannel.channel('undici:request:create') @@ -79,7 +86,7 @@ class Request { this.body = body.byteLength ? body : null } else if (typeof body === 'string') { this.body = body.length ? Buffer.from(body) : null - } else if (util.isIterable(body) || util.isBlobLike(body)) { + } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { this.body = body } else { throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') @@ -126,7 +133,22 @@ class Request { throw new InvalidArgumentError('headers must be an object or an array') } - if (util.isBlobLike(body) && this.contentType == null && body.type) { + if (util.isFormDataLike(this.body)) { + if (nodeMajor < 16 || (nodeMajor === 16 && nodeMinor < 5)) { + throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.5 and newer.') + } + + if (!extractBody) { + extractBody = require('../fetch/body.js').extractBody + } + + const [bodyStream, contentType] = extractBody(body) + if (this.contentType == null) { + this.contentType = contentType + this.headers += `content-type: ${contentType}\r\n` + } + this.body = bodyStream.stream + } else if (util.isBlobLike(body) && this.contentType == null && body.type) { this.contentType = body.type this.headers += `content-type: ${body.type}\r\n` } diff --git a/lib/fetch/body.js b/lib/fetch/body.js index 7da6eb988b0..fe8c4333b5e 100644 --- a/lib/fetch/body.js +++ b/lib/fetch/body.js @@ -71,7 +71,7 @@ function extractBody (object, keepalive = false) { // Set source to a copy of the bytes held by object. source = new Uint8Array(object) - } else if (object instanceof FormData) { + } else if (util.isFormDataLike(object)) { const boundary = '----formdata-undici-' + Math.random() const prefix = `--${boundary}\r\nContent-Disposition: form-data`