Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9d57401

Browse files
authored
fix: setEncoding should not throw on body #1125 (#3505)
1 parent ba8c073 commit 9d57401

File tree

2 files changed

+110
-8
lines changed

2 files changed

+110
-8
lines changed

lib/api/readable.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ class BodyReadable extends Readable {
201201
.resume()
202202
})
203203
}
204+
205+
/**
206+
* @param {BufferEncoding} encoding
207+
* @returns {BodyReadable}
208+
*/
209+
setEncoding (encoding) {
210+
if (Buffer.isEncoding(encoding)) {
211+
this._readableState.encoding = encoding
212+
}
213+
return this
214+
}
204215
}
205216

206217
// https://streams.spec.whatwg.org/#readablestream-locked
@@ -278,10 +289,10 @@ function consumeStart (consume) {
278289
}
279290

280291
if (state.endEmitted) {
281-
consumeEnd(this[kConsume])
292+
consumeEnd(this[kConsume], this._readableState.encoding)
282293
} else {
283294
consume.stream.on('end', function () {
284-
consumeEnd(this[kConsume])
295+
consumeEnd(this[kConsume], this._readableState.encoding)
285296
})
286297
}
287298

@@ -295,8 +306,10 @@ function consumeStart (consume) {
295306
/**
296307
* @param {Buffer[]} chunks
297308
* @param {number} length
309+
* @param {BufferEncoding} encoding
310+
* @returns {string}
298311
*/
299-
function chunksDecode (chunks, length) {
312+
function chunksDecode (chunks, length, encoding) {
300313
if (chunks.length === 0 || length === 0) {
301314
return ''
302315
}
@@ -311,7 +324,11 @@ function chunksDecode (chunks, length) {
311324
buffer[2] === 0xbf
312325
? 3
313326
: 0
314-
return buffer.utf8Slice(start, bufferLength)
327+
if (!encoding || encoding === 'utf8' || encoding === 'utf-8') {
328+
return buffer.utf8Slice(start, bufferLength)
329+
} else {
330+
return buffer.subarray(start, bufferLength).toString(encoding)
331+
}
315332
}
316333

317334
/**
@@ -339,14 +356,14 @@ function chunksConcat (chunks, length) {
339356
return buffer
340357
}
341358

342-
function consumeEnd (consume) {
359+
function consumeEnd (consume, encoding) {
343360
const { type, body, resolve, stream, length } = consume
344361

345362
try {
346363
if (type === 'text') {
347-
resolve(chunksDecode(body, length))
364+
resolve(chunksDecode(body, length, encoding))
348365
} else if (type === 'json') {
349-
resolve(JSON.parse(chunksDecode(body, length)))
366+
resolve(JSON.parse(chunksDecode(body, length, encoding)))
350367
} else if (type === 'arrayBuffer') {
351368
resolve(chunksConcat(body, length).buffer)
352369
} else if (type === 'blob') {

test/client-request.js

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ test('request body destroyed on invalid callback', async (t) => {
220220
after(() => client.destroy())
221221

222222
const body = new Readable({
223-
read () {}
223+
read () { }
224224
})
225225
try {
226226
client.request({
@@ -1252,3 +1252,88 @@ test('request post body DataView', async (t) => {
12521252

12531253
await t.completed
12541254
})
1255+
1256+
test('request multibyte json with setEncoding', async (t) => {
1257+
t = tspl(t, { plan: 1 })
1258+
1259+
const asd = Buffer.from('あいうえお')
1260+
const data = JSON.stringify({ asd })
1261+
const server = createServer((req, res) => {
1262+
res.write(data.slice(0, 1))
1263+
setTimeout(() => {
1264+
res.write(data.slice(1))
1265+
res.end()
1266+
}, 100)
1267+
})
1268+
after(server.close.bind(server))
1269+
1270+
server.listen(0, async () => {
1271+
const client = new Client(`http://localhost:${server.address().port}`)
1272+
after(client.destroy.bind(client))
1273+
1274+
const { body } = await client.request({
1275+
path: '/',
1276+
method: 'GET'
1277+
})
1278+
body.setEncoding('utf8')
1279+
t.deepStrictEqual(JSON.parse(data), await body.json())
1280+
})
1281+
1282+
await t.completed
1283+
})
1284+
1285+
test('request multibyte text with setEncoding', async (t) => {
1286+
t = tspl(t, { plan: 1 })
1287+
1288+
const data = Buffer.from('あいうえお')
1289+
const server = createServer((req, res) => {
1290+
res.write(data.slice(0, 1))
1291+
setTimeout(() => {
1292+
res.write(data.slice(1))
1293+
res.end()
1294+
}, 100)
1295+
})
1296+
after(server.close.bind(server))
1297+
1298+
server.listen(0, async () => {
1299+
const client = new Client(`http://localhost:${server.address().port}`)
1300+
after(client.destroy.bind(client))
1301+
1302+
const { body } = await client.request({
1303+
path: '/',
1304+
method: 'GET'
1305+
})
1306+
body.setEncoding('utf8')
1307+
t.deepStrictEqual(data.toString('utf8'), await body.text())
1308+
})
1309+
1310+
await t.completed
1311+
})
1312+
1313+
test('request multibyte text with setEncoding', async (t) => {
1314+
t = tspl(t, { plan: 1 })
1315+
1316+
const data = Buffer.from('あいうえお')
1317+
const server = createServer((req, res) => {
1318+
res.write(data.slice(0, 1))
1319+
setTimeout(() => {
1320+
res.write(data.slice(1))
1321+
res.end()
1322+
}, 100)
1323+
})
1324+
after(server.close.bind(server))
1325+
1326+
server.listen(0, async () => {
1327+
const client = new Client(`http://localhost:${server.address().port}`)
1328+
after(client.destroy.bind(client))
1329+
1330+
const { body } = await client.request({
1331+
path: '/',
1332+
method: 'GET'
1333+
})
1334+
body.setEncoding('hex')
1335+
t.deepStrictEqual(data.toString('hex'), await body.text())
1336+
})
1337+
1338+
await t.completed
1339+
})

0 commit comments

Comments
 (0)