fixed cors issue

This commit is contained in:
Dmitri 2026-04-09 10:22:59 +04:00
parent f8c3bb4a07
commit ef137199ec
2 changed files with 37 additions and 62 deletions

View File

@ -18,10 +18,8 @@ import {
extractStoragePath, extractStoragePath,
queuePresignedUrls, queuePresignedUrls,
isRelativeStoragePath, isRelativeStoragePath,
markPresignedUrlFailed,
markPresignedUrlsVerified, markPresignedUrlsVerified,
isPresignedUrl, isPresignedUrl,
buildProxyUrl,
} from '../lib/assetUrl'; } from '../lib/assetUrl';
import { logger } from '../lib/logger'; import { logger } from '../lib/logger';
import type { BlobUrlReadyEvent } from '../types/offline'; import type { BlobUrlReadyEvent } from '../types/offline';
@ -173,7 +171,7 @@ export function usePreloadOrchestrator(
}); });
// Use DownloadManager for unified download and blob URL creation // Use DownloadManager for unified download and blob URL creation
// Mark presigned URL as verified if download succeeds // DownloadManager automatically handles presigned URL → proxy fallback
downloadManager downloadManager
.addJob({ .addJob({
assetId: item.id, assetId: item.id,
@ -192,44 +190,11 @@ export function usePreloadOrchestrator(
markPresignedUrlsVerified(); markPresignedUrlsVerified();
} }
}) })
.catch(async (err) => { .catch((err) => {
logger.error('[PRELOAD] Download failed', { logger.error('[PRELOAD] Download failed', {
url: item.url.slice(-50), url: item.url.slice(-50),
error: err?.message, error: err?.message,
}); });
// If presigned URL failed (e.g., CORS), retry with proxy URL
if (storageKey && isPresignedUrl(item.url)) {
markPresignedUrlFailed(storageKey);
const proxyUrl = buildProxyUrl(storageKey);
logger.info('[PRELOAD] Retrying with proxy URL', {
storageKey: storageKey.slice(-50),
proxyUrl: proxyUrl.slice(-60),
});
try {
await downloadManager.addJob({
assetId: item.id,
projectId: '',
url: proxyUrl,
filename: storageKey.split('/').pop() || 'asset',
variantType: 'original',
assetType: mapAssetType(item.assetType),
priority: item.priority,
storageKey,
createBlobUrl: true,
persist: false,
});
logger.info('[PRELOAD] Proxy download complete', {
url: proxyUrl.slice(-60),
});
} catch (retryErr) {
logger.error('[PRELOAD] Proxy download also failed', {
url: proxyUrl.slice(-60),
error: retryErr instanceof Error ? retryErr.message : 'unknown',
});
}
}
}); });
preloadedUrls.add(storageKey); preloadedUrls.add(storageKey);
@ -582,6 +547,7 @@ export function usePreloadOrchestrator(
// Partial downloads (video/audio/transition) use presigned URL directly for playback // Partial downloads (video/audio/transition) use presigned URL directly for playback
const createBlobUrl = assetType === 'image' || maxBytes === undefined; const createBlobUrl = assetType === 'image' || maxBytes === undefined;
// DownloadManager automatically handles presigned URL → proxy fallback
return downloadManager return downloadManager
.addJob({ .addJob({
assetId: id, assetId: id,
@ -601,33 +567,11 @@ export function usePreloadOrchestrator(
markPresignedUrlsVerified(); markPresignedUrlsVerified();
} }
}) })
.catch(async (err) => { .catch((err) => {
logger.error('[PRELOAD] Download failed', { logger.error('[PRELOAD] Download failed', {
url: resolvedUrl.slice(-50), url: resolvedUrl.slice(-50),
error: err?.message, error: err?.message,
}); });
// Retry with proxy if presigned URL failed
if (isPresignedUrl(resolvedUrl)) {
markPresignedUrlFailed(normalizedKey);
const proxyUrl = buildProxyUrl(normalizedKey);
try {
await downloadManager.addJob({
assetId: id,
projectId: '',
url: proxyUrl,
filename: normalizedKey.split('/').pop() || 'asset',
variantType: 'original',
assetType: mapAssetType(assetType),
priority,
storageKey: normalizedKey,
createBlobUrl,
persist: false,
maxBytes, // Preserve partial preload behavior for retry
});
} catch {
// Ignore retry failures
}
}
}); });
}; };

View File

@ -10,7 +10,12 @@ import { OFFLINE_CONFIG } from '../../config/offline.config';
import { downloadEventBus } from './DownloadEventBus'; import { downloadEventBus } from './DownloadEventBus';
import { StorageManager } from './StorageManager'; import { StorageManager } from './StorageManager';
import { OfflineDbManager } from '../offlineDb/OfflineDbManager'; import { OfflineDbManager } from '../offlineDb/OfflineDbManager';
import { extractStoragePath } from '../assetUrl'; import {
extractStoragePath,
isPresignedUrl,
markPresignedUrlFailed,
buildProxyUrl,
} from '../assetUrl';
import { logger } from '../logger'; import { logger } from '../logger';
import type { import type {
PreloadJobStatus, PreloadJobStatus,
@ -39,6 +44,7 @@ interface DownloadJob {
persist?: boolean; // Persist to IndexedDB for resume (default: true) persist?: boolean; // Persist to IndexedDB for resume (default: true)
maxBytes?: number; // Partial download limit (undefined = full download) maxBytes?: number; // Partial download limit (undefined = full download)
isPartial?: boolean; // Whether this was a partial download (for tracking) isPartial?: boolean; // Whether this was a partial download (for tracking)
usedProxyFallback?: boolean; // Whether we've already tried proxy URL fallback
abortController?: AbortController; abortController?: AbortController;
resolve?: () => void; resolve?: () => void;
reject?: (error: Error) => void; reject?: (error: Error) => void;
@ -402,10 +408,35 @@ class DownloadManagerClass {
return; return;
} }
job.retryCount++;
const errorMessage = const errorMessage =
error instanceof Error ? error.message : 'Unknown error'; error instanceof Error ? error.message : 'Unknown error';
// If presigned URL failed and we haven't tried proxy yet, fall back to proxy
if (isPresignedUrl(job.url) && !job.usedProxyFallback) {
markPresignedUrlFailed(job.storageKey);
const proxyUrl = buildProxyUrl(job.storageKey);
logger.info('[DownloadManager] Presigned URL failed, retrying with proxy', {
storageKey: job.storageKey.slice(-50),
error: errorMessage,
});
// Update job to use proxy URL and retry immediately
job.url = proxyUrl;
job.usedProxyFallback = true;
job.retryCount = 0; // Reset retry count for proxy attempt
job.bytesLoaded = 0;
job.progress = 0;
job.status = 'queued';
// Retry immediately with proxy URL
this.queue.unshift(job);
this.processQueue();
return;
}
job.retryCount++;
if (job.retryCount < this.config.maxRetries) { if (job.retryCount < this.config.maxRetries) {
// Retry with backoff // Retry with backoff
job.status = 'queued'; job.status = 'queued';