Fix: range request header on response
All checks were successful
Build and push image / release-image (push) Successful in 1m34s

This commit is contained in:
2025-07-10 17:12:33 +08:00
parent 8b66e589d7
commit 6ab755d91a
2 changed files with 22 additions and 15 deletions

View File

@@ -1,7 +1,11 @@
import { Response } from 'express';
import { Readable } from 'stream';
import {
Controller,
Get,
Header,
Res,
Param,
Headers,
HttpException,
@@ -9,7 +13,9 @@ import {
StreamableFile,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ApiOkResponse, ApiNotFoundResponse } from '@nestjs/swagger';
import { GetObjectCommandInput } from '@aws-sdk/client-s3';
import { AppService } from './app.service';
@Controller()
@@ -19,15 +25,19 @@ export class AppController {
private readonly appService: AppService,
) {}
@ApiOkResponse()
@Get('healthz')
getHealthz(): string {
return this.appService.getHealthz();
}
@ApiOkResponse()
@ApiNotFoundResponse()
@Get(`:repo/os/:arch/:pkg`)
@Header('Accept-Ranges', 'bytes')
async getRepo(
@Headers('Range') range: string,
@Res({ passthrough: true }) res: Response,
@Param('repo') repo: string,
@Param('arch') arch: string,
@Param('pkg') pkg: string,
@@ -40,15 +50,18 @@ export class AppController {
HttpStatus.NOT_FOUND,
);
const stream = await this.appService.getObject({
const output = await this.appService.getObject({
Bucket: this.configService.get<string>('MINIO_BUCKET'),
Key: pkg,
Range: range,
} as GetObjectCommandInput);
if (!stream)
throw new HttpException(
`No such file '${pkg}'`, HttpStatus.NOT_FOUND);
if (!output || !output.Body)
throw new HttpException(`No such file '${pkg}'`, HttpStatus.NOT_FOUND);
return new StreamableFile(stream);
if (range !== undefined) {
res.set('Content-Length', `${output.ContentLength}`)
res.set('Content-Range', `${output.ContentRange}`)
}
return new StreamableFile(output.Body as Readable);
}
}

View File

@@ -30,22 +30,16 @@ export class AppService {
return 'OK';
}
async getObject(getObjectConfig: GetObjectCommandInput): Promise<Readable | null> {
async getObject(
getObjectConfig: GetObjectCommandInput,
): Promise<GetObjectCommandOutput | null> {
const command = new GetObjectCommand(getObjectConfig);
let res: GetObjectCommandOutput;
try {
res = await this.s3Client.send(command);
return await this.s3Client.send(command);
} catch (err: unknown) {
if (err instanceof NoSuchKey)
return null;
throw err;
}
if (!res.Body)
throw new HttpException(
's3 get object failed',
HttpStatus.INTERNAL_SERVER_ERROR,
);
return res.Body as Readable;
}
}