From a73260339fec7852b1c9a067b342bad0b87b20ee Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Thu, 21 Sep 2023 13:37:38 +0200 Subject: [PATCH 1/4] Add Khaf to releasers (#2276) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 051a9df2dea..3ba89890df6 100644 --- a/README.md +++ b/README.md @@ -436,6 +436,7 @@ and `undici.Agent`) which will enable the family autoselection algorithm when es * [__Ethan Arrowood__](https://github.com/ethan-arrowood), * [__Matteo Collina__](https://github.com/mcollina), * [__Robert Nagy__](https://github.com/ronag), +* [__Matthew Aitken__](https://github.com/KhafraDev), ## License From ba95ff6cf622a4ce8d6d9d42da22ebf9f15685a0 Mon Sep 17 00:00:00 2001 From: killa Date: Fri, 22 Sep 2023 15:43:00 +0800 Subject: [PATCH 2/4] fix: fix request with readable mode is object (#2279) In the stream Readable.from(buf) state, the length of 1 refers to the number of objects, not the length of buf. Therefore, when the stream mode is set to 'object,' should not use the length from the state. --- lib/core/util.js | 2 +- test/content-length.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/core/util.js b/lib/core/util.js index 0e6197a4b29..259ba7b38a6 100644 --- a/lib/core/util.js +++ b/lib/core/util.js @@ -168,7 +168,7 @@ function bodyLength (body) { return 0 } else if (isStream(body)) { const state = body._readableState - return state && state.ended === true && Number.isFinite(state.length) + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) ? state.length : null } else if (isBlobLike(body)) { diff --git a/test/content-length.js b/test/content-length.js index ecc1da34cc6..66c010a7c9e 100644 --- a/test/content-length.js +++ b/test/content-length.js @@ -300,3 +300,32 @@ test('response invalid content length with close', (t) => { }) }) }) + +test('request streaming with Readable.from(buf)', (t) => { + const server = createServer((req, res) => { + req.pipe(res) + }) + t.teardown(server.close.bind(server)) + server.listen(0, () => { + const client = new Client(`http://localhost:${server.address().port}`) + t.teardown(client.destroy.bind(client)) + + client.request({ + path: '/', + method: 'PUT', + body: Readable.from(Buffer.from('hello')) + }, (err, data) => { + const chunks = [] + t.error(err) + data.body + .on('data', (chunk) => { + chunks.push(chunk) + }) + .on('end', () => { + t.equal(Buffer.concat(chunks).toString(), 'hello') + t.pass() + t.end() + }) + }) + }) +}) From b85ac789de76d95de6db7d442b31feed46c671ca Mon Sep 17 00:00:00 2001 From: Khafra Date: Fri, 22 Sep 2023 13:20:21 -0400 Subject: [PATCH 3/4] fix loading websockets when node is built w/ --without-ssl (#2282) --- lib/websocket/connection.js | 13 ++++++++++--- lib/websocket/frame.js | 11 +++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/websocket/connection.js b/lib/websocket/connection.js index 8c821899f65..e0fa69726b4 100644 --- a/lib/websocket/connection.js +++ b/lib/websocket/connection.js @@ -1,6 +1,5 @@ 'use strict' -const { randomBytes, createHash } = require('crypto') const diagnosticsChannel = require('diagnostics_channel') const { uid, states } = require('./constants') const { @@ -22,6 +21,14 @@ channels.open = diagnosticsChannel.channel('undici:websocket:open') channels.close = diagnosticsChannel.channel('undici:websocket:close') channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') +/** @type {import('crypto')} */ +let crypto +try { + crypto = require('crypto') +} catch { + +} + /** * @see https://websockets.spec.whatwg.org/#concept-websocket-establish * @param {URL} url @@ -66,7 +73,7 @@ function establishWebSocketConnection (url, protocols, ws, onEstablish, options) // 5. Let keyValue be a nonce consisting of a randomly selected // 16-byte value that has been forgiving-base64-encoded and // isomorphic encoded. - const keyValue = randomBytes(16).toString('base64') + const keyValue = crypto.randomBytes(16).toString('base64') // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s // header list. @@ -148,7 +155,7 @@ function establishWebSocketConnection (url, protocols, ws, onEstablish, options) // trailing whitespace, the client MUST _Fail the WebSocket // Connection_. const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') - const digest = createHash('sha1').update(keyValue + uid).digest('base64') + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') if (secWSAccept !== digest) { failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') return diff --git a/lib/websocket/frame.js b/lib/websocket/frame.js index 61bfd3915ce..d867ad118b2 100644 --- a/lib/websocket/frame.js +++ b/lib/websocket/frame.js @@ -1,15 +1,22 @@ 'use strict' -const { randomBytes } = require('crypto') const { maxUnsigned16Bit } = require('./constants') +/** @type {import('crypto')} */ +let crypto +try { + crypto = require('crypto') +} catch { + +} + class WebsocketFrameSend { /** * @param {Buffer|undefined} data */ constructor (data) { this.frameData = data - this.maskKey = randomBytes(4) + this.maskKey = crypto.randomBytes(4) } createFrame (opcode) { From 4013c4b8932e73728809e4106d5c9d9d40648031 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 22 Sep 2023 19:37:05 +0200 Subject: [PATCH 4/4] Bumped v5.25.2 Signed-off-by: Matteo Collina --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eef22bf6a05..3846b9dc398 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.25.1", + "version": "5.25.2", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": {