You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks so much for sharing this library and for accepting my bug fix. I ended up creating a refactored version of your code while investigating the bug. If you're interested, here's what I put together. I think it utilizes Node streaming concepts a bit more cleanly. Wanted to share it just in case you're interested in these same ideas since you were generous enough to share your code.
importcalculateEtagfrom"etag";import{Context,Middleware}from"koa";import{Stream,Transform,TransformCallback}from"stream";typeOptions={weak?: boolean;sizeLimit?: number;};constDEFAULT_SIZE_LIMIT=1024*1024;exportdefaultfunctionetag(options?: Options): Middleware{returnasync(ctx,next)=>{awaitnext();constbody=ctx.body;if(!body||ctx.response.get("etag")||ctx.status/100!==2){return;}constoutputStream=newETagStream({ ctx, ...options});if(bodyinstanceofStream){body.pipe(outputStream);}else{outputStream.end(typeofbody==="string"||Buffer.isBuffer(body)
? body
: JSON.stringify(body));}ctx.body=outputStream;};}classETagStreamextendsTransform{privatectx: Context;privatesizeLimit: number;privateweak: boolean;privateisCalculating: boolean=true;privatecontentSize: number=0;privatebufferedChunks: Array<Buffer>=[];constructor({
ctx,
sizeLimit =DEFAULT_SIZE_LIMIT,
weak =false,}: {ctx: Context;sizeLimit?: number;weak?: boolean;}){super({writableHighWaterMark: sizeLimit});this.ctx=ctx;this.sizeLimit=sizeLimit;this.weak=weak;}_transform(chunk: Buffer,_encoding: BufferEncoding,callback: TransformCallback){if(!this.isCalculating){// We've already cancelled calculating the ETag, so just pass throughreturnvoidcallback(null,chunk);}this.bufferedChunks.push(chunk);this.contentSize+=chunk.length;if(this.contentSize>this.sizeLimit){// Bail on completing the calculation and flush the buffered data so farthis.isCalculating=false;returnvoidthis._flush(callback);}// Hold the data until we have enough data to calculate the ETagreturnvoidcallback();}_flush(callback: TransformCallback){if(this.isCalculating){// We've reached the end of the stream; finalize etag calculationconstentity=Buffer.concat(this.bufferedChunks);this.ctx.response.etag=calculateEtag(entity,{weak: this.weak});}// Flush the buffered dataletbufferedChunk;while((bufferedChunk=this.bufferedChunks.shift())){this.push(bufferedChunk);}returnvoidcallback();}}
The text was updated successfully, but these errors were encountered:
Thanks so much for sharing this library and for accepting my bug fix. I ended up creating a refactored version of your code while investigating the bug. If you're interested, here's what I put together. I think it utilizes Node streaming concepts a bit more cleanly. Wanted to share it just in case you're interested in these same ideas since you were generous enough to share your code.
The text was updated successfully, but these errors were encountered: