Comparing version 7.2.0 to 7.2.1
@@ -43,3 +43,3 @@ # Diagnostics Channel Support | ||
This message is published after the response headers have been received, i.e. the response has been completed. | ||
This message is published after the response headers have been received. | ||
@@ -46,0 +46,0 @@ ```js |
@@ -655,3 +655,3 @@ # Dispatcher | ||
As demonstrated in [Example 1 - Basic GET stream request](/docs/docs/api/Dispatcher.md#example-1---basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](/docs/docs/api/Dispatch.md#example-2---stream-to-fastify-response) for more details. | ||
As demonstrated in [Example 1 - Basic GET stream request](/docs/docs/api/Dispatcher.md#example-1-basic-get-stream-request), it is recommended to use the `option.opaque` property to avoid creating a closure for the `factory` method. This pattern works well with Node.js Web Frameworks such as [Fastify](https://fastify.io). See [Example 2 - Stream to Fastify Response](/docs/docs/api/Dispatch.md#example-2-stream-to-fastify-response) for more details. | ||
@@ -658,0 +658,0 @@ Arguments: |
@@ -136,3 +136,3 @@ 'use strict' | ||
setTimeout(() => cb(null), retryTimeout).unref() | ||
setTimeout(() => cb(null), retryTimeout) | ||
} | ||
@@ -281,3 +281,3 @@ | ||
onResponseError (controller, err) { | ||
if (!controller || controller.aborted || isDisturbed(this.opts.body)) { | ||
if (controller?.aborted || isDisturbed(this.opts.body)) { | ||
this.handler.onResponseError?.(controller, err) | ||
@@ -284,0 +284,0 @@ return |
@@ -356,3 +356,3 @@ 'use strict' | ||
if (err) { | ||
return handler.onError(err) | ||
return handler.onResponseError(null, err) | ||
} | ||
@@ -359,0 +359,0 @@ |
@@ -27,2 +27,3 @@ 'use strict' | ||
#buffers = [] | ||
#fragmentsBytes = 0 | ||
#byteOffset = 0 | ||
@@ -212,3 +213,3 @@ #loop = false | ||
if (!this.#info.compressed) { | ||
this.#fragments.push(body) | ||
this.writeFragments(body) | ||
@@ -220,5 +221,3 @@ // If the frame is not fragmented, a message has been received. | ||
if (!this.#info.fragmented && this.#info.fin) { | ||
const fullMessage = Buffer.concat(this.#fragments) | ||
websocketMessageReceived(this.#handler, this.#info.binaryType, fullMessage) | ||
this.#fragments.length = 0 | ||
websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments()) | ||
} | ||
@@ -234,3 +233,3 @@ | ||
this.#fragments.push(data) | ||
this.writeFragments(data) | ||
@@ -244,7 +243,6 @@ if (!this.#info.fin) { | ||
websocketMessageReceived(this.#handler, this.#info.binaryType, Buffer.concat(this.#fragments)) | ||
websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments()) | ||
this.#loop = true | ||
this.#state = parserStates.INFO | ||
this.#fragments.length = 0 | ||
this.run(callback) | ||
@@ -273,30 +271,66 @@ }) | ||
if (this.#buffers[0].length === n) { | ||
this.#byteOffset -= this.#buffers[0].length | ||
this.#byteOffset -= n | ||
const first = this.#buffers[0] | ||
if (first.length > n) { | ||
// replace with remaining buffer | ||
this.#buffers[0] = first.subarray(n, first.length) | ||
return first.subarray(0, n) | ||
} else if (first.length === n) { | ||
// prefect match | ||
return this.#buffers.shift() | ||
} else { | ||
let offset = 0 | ||
// If Buffer.allocUnsafe is used, extra copies will be made because the offset is non-zero. | ||
const buffer = Buffer.allocUnsafeSlow(n) | ||
while (offset !== n) { | ||
const next = this.#buffers[0] | ||
const length = next.length | ||
if (length + offset === n) { | ||
buffer.set(this.#buffers.shift(), offset) | ||
break | ||
} else if (length + offset > n) { | ||
buffer.set(next.subarray(0, n - offset), offset) | ||
this.#buffers[0] = next.subarray(n - offset) | ||
break | ||
} else { | ||
buffer.set(this.#buffers.shift(), offset) | ||
offset += length | ||
} | ||
} | ||
return buffer | ||
} | ||
} | ||
const buffer = Buffer.allocUnsafe(n) | ||
let offset = 0 | ||
writeFragments (fragment) { | ||
this.#fragmentsBytes += fragment.length | ||
this.#fragments.push(fragment) | ||
} | ||
while (offset !== n) { | ||
const next = this.#buffers[0] | ||
const { length } = next | ||
consumeFragments () { | ||
const fragments = this.#fragments | ||
if (length + offset === n) { | ||
buffer.set(this.#buffers.shift(), offset) | ||
break | ||
} else if (length + offset > n) { | ||
buffer.set(next.subarray(0, n - offset), offset) | ||
this.#buffers[0] = next.subarray(n - offset) | ||
break | ||
} else { | ||
buffer.set(this.#buffers.shift(), offset) | ||
offset += next.length | ||
} | ||
if (fragments.length === 1) { | ||
// single fragment | ||
this.#fragmentsBytes = 0 | ||
return fragments.shift() | ||
} | ||
this.#byteOffset -= n | ||
let offset = 0 | ||
// If Buffer.allocUnsafe is used, extra copies will be made because the offset is non-zero. | ||
const output = Buffer.allocUnsafeSlow(this.#fragmentsBytes) | ||
return buffer | ||
for (let i = 0; i < fragments.length; ++i) { | ||
const buffer = fragments[i] | ||
output.set(buffer, offset) | ||
offset += buffer.length | ||
} | ||
this.#fragments = [] | ||
this.#fragmentsBytes = 0 | ||
return output | ||
} | ||
@@ -303,0 +337,0 @@ |
@@ -90,3 +90,3 @@ 'use strict' | ||
} | ||
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) | ||
return new Uint8Array(buffer).buffer | ||
} | ||
@@ -93,0 +93,0 @@ |
{ | ||
"name": "undici", | ||
"version": "7.2.0", | ||
"version": "7.2.1", | ||
"description": "An HTTP/1.1 client, written from scratch for Node.js", | ||
@@ -110,3 +110,3 @@ "homepage": "https://undici.nodejs.org", | ||
"devDependencies": { | ||
"@fastify/busboy": "3.1.0", | ||
"@fastify/busboy": "3.1.1", | ||
"@matteo.collina/tspl": "^0.1.1", | ||
@@ -113,0 +113,0 @@ "@sinonjs/fake-timers": "^12.0.0", |
@@ -36,2 +36,18 @@ import { IncomingHttpHeaders } from './header' | ||
export class ResponseError extends UndiciError { | ||
constructor ( | ||
message: string, | ||
code: number, | ||
options: { | ||
headers?: IncomingHttpHeaders | string[] | null, | ||
body?: null | Record<string, any> | string | ||
} | ||
) | ||
name: 'ResponseError' | ||
code: 'UND_ERR_RESPONSE' | ||
statusCode: number | ||
body: null | Record<string, any> | string | ||
headers: IncomingHttpHeaders | string[] | null | ||
} | ||
export class ResponseStatusCodeError extends UndiciError { | ||
@@ -38,0 +54,0 @@ constructor ( |
1296302
28074