mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 20:43:30 +01:00
fix(WebSocketShard): buffer native zlib decompression payload (#10416)
* fix(WebSocketShard): buffer native zlib decompression payload * refactor: nit Co-authored-by: Almeida <almeidx@pm.me> --------- Co-authored-by: Almeida <almeidx@pm.me> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -98,6 +98,13 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
|||||||
|
|
||||||
private zLibSyncInflate: ZlibSync.Inflate | null = null;
|
private zLibSyncInflate: ZlibSync.Inflate | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @privateRemarks
|
||||||
|
*
|
||||||
|
* Used only for native zlib inflate, zlib-sync buffering is handled by the library itself.
|
||||||
|
*/
|
||||||
|
private inflateBuffer: Buffer[] = [];
|
||||||
|
|
||||||
private readonly textDecoder = new TextDecoder();
|
private readonly textDecoder = new TextDecoder();
|
||||||
|
|
||||||
private replayedEvents = 0;
|
private replayedEvents = 0;
|
||||||
@@ -198,11 +205,17 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
|||||||
case CompressionMethod.ZlibNative: {
|
case CompressionMethod.ZlibNative: {
|
||||||
const zlib = await getNativeZlib();
|
const zlib = await getNativeZlib();
|
||||||
if (zlib) {
|
if (zlib) {
|
||||||
|
this.inflateBuffer = [];
|
||||||
|
|
||||||
const inflate = zlib.createInflate({
|
const inflate = zlib.createInflate({
|
||||||
chunkSize: 65_535,
|
chunkSize: 65_535,
|
||||||
flush: zlib.constants.Z_SYNC_FLUSH,
|
flush: zlib.constants.Z_SYNC_FLUSH,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
inflate.on('data', (chunk) => {
|
||||||
|
this.inflateBuffer.push(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
inflate.on('error', (error) => {
|
inflate.on('error', (error) => {
|
||||||
this.emit(WebSocketShardEvents.Error, error);
|
this.emit(WebSocketShardEvents.Error, error);
|
||||||
});
|
});
|
||||||
@@ -627,14 +640,28 @@ export class WebSocketShard extends AsyncEventEmitter<WebSocketShardEventsMap> {
|
|||||||
decompressable.at(-1) === 0xff;
|
decompressable.at(-1) === 0xff;
|
||||||
|
|
||||||
if (this.nativeInflate) {
|
if (this.nativeInflate) {
|
||||||
this.nativeInflate.write(decompressable, 'binary');
|
const doneWriting = new Promise<void>((resolve) => {
|
||||||
|
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
||||||
|
this.nativeInflate!.write(decompressable, 'binary', (error) => {
|
||||||
|
if (error) {
|
||||||
|
this.emit(WebSocketShardEvents.Error, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (!flush) {
|
if (!flush) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [result] = await once(this.nativeInflate, 'data');
|
// This way we're ensuring the latest write has flushed and our buffer is ready
|
||||||
return this.parseInflateResult(result);
|
await doneWriting;
|
||||||
|
|
||||||
|
const result = this.parseInflateResult(Buffer.concat(this.inflateBuffer));
|
||||||
|
this.inflateBuffer = [];
|
||||||
|
|
||||||
|
return result;
|
||||||
} else if (this.zLibSyncInflate) {
|
} else if (this.zLibSyncInflate) {
|
||||||
const zLibSync = (await getZlibSync())!;
|
const zLibSync = (await getZlibSync())!;
|
||||||
this.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);
|
this.zLibSyncInflate.push(Buffer.from(decompressable), flush ? zLibSync.Z_SYNC_FLUSH : zLibSync.Z_NO_FLUSH);
|
||||||
|
|||||||
Reference in New Issue
Block a user