@@ -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' )
@@ -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,42 @@ 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+
1516+ // TODO (fix): Error if stream is disturbed?
1517+
1518+ if ( util . isStream ( body ) && ( body . readableEnded || body . errored ) ) {
1519+ let err = body . errored
1520+ if ( ! err ) {
1521+ err = new RequestAbortedError ( )
1522+ util . destroy ( body , err )
1523+ }
1524+ body . on ( 'error' , ( ) => { } )
1525+ errorRequest ( client , request , err )
1526+ return false
1527+ }
1528+
14971529 if ( body && typeof body . read === 'function' ) {
14981530 // Try to read EOF in order to get length.
14991531 body . read ( 0 )
15001532 }
15011533
15021534 const bodyLength = util . bodyLength ( body )
15031535
1504- let contentLength = bodyLength
1536+ contentLength = bodyLength ?? contentLength
15051537
15061538 if ( contentLength === null ) {
15071539 contentLength = request . contentLength
@@ -1544,6 +1576,7 @@ function write (client, request) {
15441576 }
15451577
15461578 if ( request . aborted ) {
1579+ util . destroy ( body )
15471580 return false
15481581 }
15491582
@@ -2050,6 +2083,10 @@ function writeStream ({ h2stream, body, client, request, socket, contentLength,
20502083 socket
20512084 . on ( 'drain' , onDrain )
20522085 . on ( 'error' , onFinished )
2086+
2087+ if ( body . closeEmitted ?? body . closed ) {
2088+ queueMicrotask ( onClose )
2089+ }
20532090}
20542091
20552092async function writeBlob ( { h2stream, body, client, request, socket, contentLength, header, expectsPayload } ) {
0 commit comments