diff --git a/.changeset/fix-avatar-zero-size-header.md b/.changeset/fix-avatar-zero-size-header.md new file mode 100644 index 0000000000000..bf6e90ee53426 --- /dev/null +++ b/.changeset/fix-avatar-zero-size-header.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fix `Content-Length` header being omitted when avatar file size is zero, violating HTTP spec. diff --git a/apps/meteor/server/routes/avatar/utils.spec.ts b/apps/meteor/server/routes/avatar/utils.spec.ts index 5c31e286467ab..0b10f3a74a39d 100644 --- a/apps/meteor/server/routes/avatar/utils.spec.ts +++ b/apps/meteor/server/routes/avatar/utils.spec.ts @@ -81,6 +81,19 @@ describe('#serveAvatarFile()', () => { expect(response.setHeader.getCall(3).calledWith('Content-Length', file.size)).to.be.true; expect(mocks.fileUploadGet.calledWith(file, request, response, next)).to.be.true; }); + + it('should serve avatar and set Content-Length 0 when file size is exactly 0', () => { + const zeroSizeFile = { uploadedAt: new Date(0), type: 'image/png', size: 0 }; + const request = { headers: { 'if-modified-since': new Date(200000).toUTCString() } }; + serveAvatarFile(zeroSizeFile, request, response, next); + + const contentLengthCall = response.setHeader.getCalls().find( + (c) => c.args[0] === 'Content-Length' + ); + + expect(contentLengthCall).to.exist; + expect(contentLengthCall?.args[1]).to.equal(0); + }); }); describe('#serveSvgAvatarInRequestedFormat()', () => { diff --git a/apps/meteor/server/routes/avatar/utils.ts b/apps/meteor/server/routes/avatar/utils.ts index 9dbb50719ab13..512ee9f76ba88 100644 --- a/apps/meteor/server/routes/avatar/utils.ts +++ b/apps/meteor/server/routes/avatar/utils.ts @@ -40,7 +40,7 @@ export const serveAvatarFile = (file: IUpload, req: IIncomingMessage, res: Serve res.setHeader('Content-Type', file.type); } - if (file.size) { + if (typeof file.size === 'number') { res.setHeader('Content-Length', file.size); }