Fix: range request header on response
All checks were successful
Build and push image / release-image (push) Successful in 1m34s
All checks were successful
Build and push image / release-image (push) Successful in 1m34s
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
|
import { Response } from 'express';
|
||||||
|
import { Readable } from 'stream';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
Header,
|
Header,
|
||||||
|
Res,
|
||||||
Param,
|
Param,
|
||||||
Headers,
|
Headers,
|
||||||
HttpException,
|
HttpException,
|
||||||
@@ -9,7 +13,9 @@ import {
|
|||||||
StreamableFile,
|
StreamableFile,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
import { ApiOkResponse, ApiNotFoundResponse } from '@nestjs/swagger';
|
||||||
import { GetObjectCommandInput } from '@aws-sdk/client-s3';
|
import { GetObjectCommandInput } from '@aws-sdk/client-s3';
|
||||||
|
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@@ -19,15 +25,19 @@ export class AppController {
|
|||||||
private readonly appService: AppService,
|
private readonly appService: AppService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
@Get('healthz')
|
@Get('healthz')
|
||||||
getHealthz(): string {
|
getHealthz(): string {
|
||||||
return this.appService.getHealthz();
|
return this.appService.getHealthz();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
|
@ApiNotFoundResponse()
|
||||||
@Get(`:repo/os/:arch/:pkg`)
|
@Get(`:repo/os/:arch/:pkg`)
|
||||||
@Header('Accept-Ranges', 'bytes')
|
@Header('Accept-Ranges', 'bytes')
|
||||||
async getRepo(
|
async getRepo(
|
||||||
@Headers('Range') range: string,
|
@Headers('Range') range: string,
|
||||||
|
@Res({ passthrough: true }) res: Response,
|
||||||
@Param('repo') repo: string,
|
@Param('repo') repo: string,
|
||||||
@Param('arch') arch: string,
|
@Param('arch') arch: string,
|
||||||
@Param('pkg') pkg: string,
|
@Param('pkg') pkg: string,
|
||||||
@@ -40,15 +50,18 @@ export class AppController {
|
|||||||
HttpStatus.NOT_FOUND,
|
HttpStatus.NOT_FOUND,
|
||||||
);
|
);
|
||||||
|
|
||||||
const stream = await this.appService.getObject({
|
const output = await this.appService.getObject({
|
||||||
Bucket: this.configService.get<string>('MINIO_BUCKET'),
|
Bucket: this.configService.get<string>('MINIO_BUCKET'),
|
||||||
Key: pkg,
|
Key: pkg,
|
||||||
Range: range,
|
Range: range,
|
||||||
} as GetObjectCommandInput);
|
} as GetObjectCommandInput);
|
||||||
if (!stream)
|
if (!output || !output.Body)
|
||||||
throw new HttpException(
|
throw new HttpException(`No such file '${pkg}'`, HttpStatus.NOT_FOUND);
|
||||||
`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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,22 +30,16 @@ export class AppService {
|
|||||||
return 'OK';
|
return 'OK';
|
||||||
}
|
}
|
||||||
|
|
||||||
async getObject(getObjectConfig: GetObjectCommandInput): Promise<Readable | null> {
|
async getObject(
|
||||||
|
getObjectConfig: GetObjectCommandInput,
|
||||||
|
): Promise<GetObjectCommandOutput | null> {
|
||||||
const command = new GetObjectCommand(getObjectConfig);
|
const command = new GetObjectCommand(getObjectConfig);
|
||||||
let res: GetObjectCommandOutput;
|
|
||||||
try {
|
try {
|
||||||
res = await this.s3Client.send(command);
|
return await this.s3Client.send(command);
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (err instanceof NoSuchKey)
|
if (err instanceof NoSuchKey)
|
||||||
return null;
|
return null;
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
if (!res.Body)
|
|
||||||
throw new HttpException(
|
|
||||||
's3 get object failed',
|
|
||||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
);
|
|
||||||
|
|
||||||
return res.Body as Readable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user