diff --git a/e2e/src/api/specs/asset-upload.e2e-spec.ts b/e2e/src/api/specs/asset-upload.e2e-spec.ts index a2f70dccac..082b1a6599 100644 --- a/e2e/src/api/specs/asset-upload.e2e-spec.ts +++ b/e2e/src/api/specs/asset-upload.e2e-spec.ts @@ -974,7 +974,7 @@ describe('/upload', () => { expect(status).toBe(204); expect(headers['upload-offset']).toBe('512'); expect(headers['upload-complete']).toBe('?0'); - expect(headers['upload-limit']).toEqual('min-size=0, max-age=259200'); + expect(headers['upload-limit']).toEqual('min-size=1, max-age=259200'); expect(headers['cache-control']).toBe('no-store'); }); @@ -993,7 +993,7 @@ describe('/upload', () => { const { status, headers } = await request(app).options('/upload'); expect(status).toBe(204); - expect(headers['upload-limit']).toEqual('min-size=0, max-age=259200'); + expect(headers['upload-limit']).toEqual('min-size=1, max-age=259200'); }); }); }); diff --git a/server/src/controllers/asset-upload.controller.spec.ts b/server/src/controllers/asset-upload.controller.spec.ts index e836bfcb1a..c94b29cc54 100644 --- a/server/src/controllers/asset-upload.controller.spec.ts +++ b/server/src/controllers/asset-upload.controller.spec.ts @@ -115,20 +115,7 @@ describe(AssetUploadController.name, () => { expect(body).toEqual(expect.objectContaining({ message: 'Expected valid upload-complete header' })); }); - it('should require Upload-Length header', async () => { - const { status, body } = await request(ctx.getHttpServer()) - .post('/upload') - .set('Upload-Draft-Interop-Version', '8') - .set('X-Immich-Asset-Data', makeAssetData()) - .set('Repr-Digest', checksum) - .set('Upload-Complete', '?0') - .send(buffer); - - expect(status).toBe(400); - expect(body).toEqual(expect.objectContaining({ message: 'Missing upload-length header' })); - }); - - it('should infer upload length from content length if complete upload', async () => { + it('should infer upload length from non-empty content length if complete upload', async () => { const { status } = await request(ctx.getHttpServer()) .post('/upload') .set('Upload-Draft-Interop-Version', '8') @@ -258,7 +245,7 @@ describe(AssetUploadController.name, () => { expect(body).toEqual(expect.objectContaining({ message: 'Expected valid upload-complete header' })); }); - it('should validate Upload-Length is a non-negative integer', async () => { + it('should validate Upload-Length is a positive integer', async () => { const { status, body } = await request(ctx.getHttpServer()) .post('/upload') .set('Upload-Draft-Interop-Version', '8') @@ -271,7 +258,7 @@ describe(AssetUploadController.name, () => { expect(status).toBe(400); expect(body).toEqual( expect.objectContaining({ - message: expect.arrayContaining(['uploadLength must not be less than 0']), + message: expect.arrayContaining(['uploadLength must not be less than 1']), }), ); }); diff --git a/server/src/dtos/asset-upload.dto.ts b/server/src/dtos/asset-upload.dto.ts index 0442005088..bab4d1e8a9 100644 --- a/server/src/dtos/asset-upload.dto.ts +++ b/server/src/dtos/asset-upload.dto.ts @@ -112,7 +112,7 @@ export class StartUploadDto extends BaseUploadHeadersDto { checksum!: Buffer; @Expose() - @Min(0) + @Min(1) @IsInt() @Transform(({ obj }) => { const uploadLength = obj[Header.UploadLength]; @@ -121,7 +121,7 @@ export class StartUploadDto extends BaseUploadHeadersDto { } const contentLength = obj[Header.ContentLength]; - if (contentLength != undefined && isUploadComplete(obj)) { + if (contentLength && isUploadComplete(obj)) { return Number(contentLength); } throw new BadRequestException(`Missing ${Header.UploadLength} header`); @@ -136,7 +136,7 @@ export class ResumeUploadDto extends BaseUploadHeadersDto { contentType!: string; @Expose({ name: Header.UploadLength }) - @Min(0) + @Min(1) @IsInt() @Type(() => Number) @Optional() diff --git a/server/src/services/asset-upload.service.ts b/server/src/services/asset-upload.service.ts index ec702c364b..71fe3487b8 100644 --- a/server/src/services/asset-upload.service.ts +++ b/server/src/services/asset-upload.service.ts @@ -440,6 +440,6 @@ export class AssetUploadService extends BaseService { } private getUploadLimits({ upload }: SystemConfig['backup']) { - return `min-size=0, max-age=${upload.maxAgeHours * 3600}`; + return `min-size=1, max-age=${upload.maxAgeHours * 3600}`; } }