mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
fix(api): bound storage listings, ranges and search paging (#2344)
This commit is contained in:
1 parent
e86e24a2db
commit
c79c0ee138
8 files changed
+479
-130
No files matched your search
@@ -11,7 +11,12 @@ import type {
|
||||
DesktopPlatform,
|
||||
} from '@fluxer/schema/src/domains/download/DownloadSchemas';
|
||||
import {Config} from '../Config';
|
||||
import type {IStorageService} from '../infrastructure/IStorageService';
|
||||
import {
|
||||
type IStorageService,
|
||||
StorageObjectListingOverflowError,
|
||||
StorageObjectRangeNotSatisfiableError,
|
||||
} from '../infrastructure/IStorageService';
|
||||
import {Logger} from '../Logger';
|
||||
import {isJsonRecord, parseJsonUnknown} from '../utils/JsonBoundaryUtils';
|
||||
import {
|
||||
parseDesktopArtifactScope,
|
||||
@@ -45,10 +50,14 @@ function isStorageNotFoundError(error: unknown): boolean {
|
||||
}
|
||||
|
||||
function isUnsatisfiableRangeError(error: unknown): boolean {
|
||||
if (error instanceof StorageObjectRangeNotSatisfiableError) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
error instanceof S3ServiceException && (error.name === 'InvalidRange' || error.$metadata?.httpStatusCode === 416)
|
||||
);
|
||||
}
|
||||
const MAX_DESKTOP_OBJECTS_PER_PREFIX = 10_000;
|
||||
const DESKTOP_BUCKET_PREFIX = 'desktop';
|
||||
const DESKTOP_TEST_BUCKET_PREFIX = 'desktop-test';
|
||||
const DOWNLOAD_KEY_ALLOWED_PREFIXES = [`${DESKTOP_BUCKET_PREFIX}/`, `${DESKTOP_TEST_BUCKET_PREFIX}/`];
|
||||
@@ -349,11 +358,8 @@ export class DownloadService {
|
||||
}
|
||||
const prefix = `${basePrefix}/`;
|
||||
try {
|
||||
const objects = await this.storageService.listObjects({
|
||||
bucket: Config.s3.buckets.downloads,
|
||||
prefix,
|
||||
});
|
||||
if (!objects || objects.length === 0) {
|
||||
const objects = await this.listDesktopArtifacts(prefix);
|
||||
if (objects.length === 0) {
|
||||
return {versions: [], hasMore: false};
|
||||
}
|
||||
const versionMap = new Map<
|
||||
@@ -791,6 +797,22 @@ export class DownloadService {
|
||||
return this.findLatestFilenameForRequestedArch(params);
|
||||
}
|
||||
|
||||
private async listDesktopArtifacts(prefix: string): Promise<ReadonlyArray<{key: string; lastModified?: Date}>> {
|
||||
try {
|
||||
return await this.storageService.listObjects({
|
||||
bucket: Config.s3.buckets.downloads,
|
||||
prefix,
|
||||
maxObjects: MAX_DESKTOP_OBJECTS_PER_PREFIX,
|
||||
});
|
||||
} catch (error) {
|
||||
if (error instanceof StorageObjectListingOverflowError) {
|
||||
Logger.warn({prefix, maxObjects: error.maxObjects}, 'Desktop artifact prefix outgrew its listing cap');
|
||||
return [];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private isFilenameCompatibleWithRequestedArch(params: ManifestFilenameResolutionParams): boolean {
|
||||
const parsed = this.parseVersionFromFilename(params.filename, params.channel, params.plat, params.arch);
|
||||
if (!parsed) {
|
||||
@@ -815,11 +837,8 @@ export class DownloadService {
|
||||
return null;
|
||||
}
|
||||
const prefix = `${basePrefix}/`;
|
||||
const objects = await this.storageService.listObjects({
|
||||
bucket: Config.s3.buckets.downloads,
|
||||
prefix,
|
||||
});
|
||||
if (!objects || objects.length === 0) {
|
||||
const objects = await this.listDesktopArtifacts(prefix);
|
||||
if (objects.length === 0) {
|
||||
return null;
|
||||
}
|
||||
let latestFilename: string | null = null;
|
||||
|
||||
Reference in new issue
Block a user