@@ -105,6 +105,8 @@ const {
105105// Experimental
106106let h2ExperimentalWarned = false
107107
108+ let extractBody
109+
108110const FastBuffer = Buffer [ Symbol . species ]
109111
110112const kClosedResolve = Symbol ( 'kClosedResolve' )
@@ -1446,7 +1448,7 @@ function _resume (client, sync) {
14461448 }
14471449
14481450 if ( client [ kRunning ] > 0 && util . bodyLength ( request . body ) !== 0 &&
1449- ( util . isStream ( request . body ) || util . isAsyncIterable ( request . body ) ) ) {
1451+ ( util . isStream ( request . body ) || util . isAsyncIterable ( request . body ) || util . isFormDataLike ( request . body ) ) ) {
14501452 // Request with stream or iterator body can error while other requests
14511453 // are inflight and indirectly error those as well.
14521454 // Ensure this doesn't happen by waiting for inflight
@@ -1477,7 +1479,9 @@ function write (client, request) {
14771479 return
14781480 }
14791481
1480- const { body, method, path, host, upgrade, headers, blocking, reset } = request
1482+ const { method, path, host, upgrade, blocking, reset } = request
1483+
1484+ let { body, headers, contentLength } = request
14811485
14821486 // https://tools.ietf.org/html/rfc7231#section-4.3.1
14831487 // https://tools.ietf.org/html/rfc7231#section-4.3.2
@@ -1494,14 +1498,29 @@ function write (client, request) {
14941498 method === 'PATCH'
14951499 )
14961500
1501+ if ( util . isFormDataLike ( body ) ) {
1502+ if ( ! extractBody ) {
1503+ extractBody = require ( './fetch/body.js' ) . extractBody
1504+ }
1505+
1506+ const [ bodyStream , contentType ] = extractBody ( body )
1507+ if ( request . contentType == null ) {
1508+ headers += `content-type: ${ contentType } \r\n`
1509+ }
1510+ body = bodyStream . stream
1511+ contentLength = bodyStream . length
1512+ } else if ( util . isBlobLike ( body ) && request . contentType == null && body . type ) {
1513+ headers += `content-type: ${ body . type } \r\n`
1514+ }
1515+
14971516 if ( body && typeof body . read === 'function' ) {
14981517 // Try to read EOF in order to get length.
14991518 body . read ( 0 )
15001519 }
15011520
15021521 const bodyLength = util . bodyLength ( body )
15031522
1504- let contentLength = bodyLength
1523+ contentLength = bodyLength ?? contentLength
15051524
15061525 if ( contentLength === null ) {
15071526 contentLength = request . contentLength
@@ -1544,6 +1563,7 @@ function write (client, request) {
15441563 }
15451564
15461565 if ( request . aborted ) {
1566+ util . destroy ( body )
15471567 return false
15481568 }
15491569
@@ -2050,6 +2070,16 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength,
20502070 socket
20512071 . on ( 'drain' , onDrain )
20522072 . on ( 'error' , onFinished )
2073+
2074+ if ( body . errorEmitted ?? body . errored ) {
2075+ setImmediate ( ( ) => onFinished ( body . errored ) )
2076+ } else if ( body . endEmitted ?? body . readableEnded ) {
2077+ setImmediate ( ( ) => onFinished ( null ) )
2078+ }
2079+
2080+ if ( body . closeEmitted ?? body . closed ) {
2081+ setImmediate ( onClose )
2082+ }
20532083}
20542084
20552085async function writeBlob ( { h2stream, body, client, request, socket, contentLength, header, expectsPayload } ) {
0 commit comments