Skip to content

Commit 8788208

Browse files
committed
fix: handle request body as late as possible
1 parent 0a069ab commit 8788208

File tree

4 files changed

+29
-22
lines changed

4 files changed

+29
-22
lines changed

lib/client.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ const {
105105
// Experimental
106106
let h2ExperimentalWarned = false
107107

108+
let extractBody
109+
108110
const FastBuffer = Buffer[Symbol.species]
109111

110112
const 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,34 @@ 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+
if (util.isStream(body) && util.isDestroyed(body)) {
1524+
errorRequest(client, request, body.errored ?? new RequestAbortedError())
1525+
return false
1526+
}
1527+
1528+
contentLength = bodyLength ?? contentLength
15051529

15061530
if (contentLength === null) {
15071531
contentLength = request.contentLength
@@ -1544,6 +1568,7 @@ function write (client, request) {
15441568
}
15451569

15461570
if (request.aborted) {
1571+
util.destroy(body)
15471572
return false
15481573
}
15491574

lib/core/request.js

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ const invalidPathRegex = /[^\u0021-\u00ff]/
2626

2727
const kHandler = Symbol('handler')
2828

29-
let extractBody
30-
3129
class Request {
3230
constructor (origin, {
3331
path,
@@ -173,23 +171,6 @@ class Request {
173171
throw new InvalidArgumentError('headers must be an object or an array')
174172
}
175173

176-
if (util.isFormDataLike(this.body)) {
177-
if (!extractBody) {
178-
extractBody = require('../fetch/body.js').extractBody
179-
}
180-
181-
const [bodyStream, contentType] = extractBody(body)
182-
if (this.contentType == null) {
183-
this.contentType = contentType
184-
this.headers += `content-type: ${contentType}\r\n`
185-
}
186-
this.body = bodyStream.stream
187-
this.contentLength = bodyStream.length
188-
} else if (util.isBlobLike(body) && this.contentType == null && body.type) {
189-
this.contentType = body.type
190-
this.headers += `content-type: ${body.type}\r\n`
191-
}
192-
193174
util.validateHandler(handler, method, upgrade)
194175

195176
this.servername = util.getServerName(this.host)

lib/core/util.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ function bodyLength (body) {
183183
}
184184

185185
function isDestroyed (stream) {
186-
return !stream || !!(stream.destroyed || stream[kDestroyed])
186+
return stream && !!(stream.destroyed || stream[kDestroyed])
187187
}
188188

189189
function isReadableAborted (stream) {

test/client.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ test('basic POST with empty stream', (t) => {
10551055
method: 'POST',
10561056
body
10571057
}, (err, { statusCode, headers, body }) => {
1058+
console.error(err)
10581059
t.error(err)
10591060
body
10601061
.on('data', () => {

0 commit comments

Comments
 (0)