reject empty file

This commit is contained in:
mertalev 2025-10-10 21:08:16 -04:00
parent 504d8dc96c
commit 85a3854208
No known key found for this signature in database
GPG key ID: DF6ABC77AAD98C95
4 changed files with 9 additions and 22 deletions

View file

@ -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');
});
});
});

View file

@ -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']),
}),
);
});

View file

@ -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()

View file

@ -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}`;
}
}