diff --git a/Extensions/Firefox b/Extensions/Firefox index e2b2ec7..b564859 160000 --- a/Extensions/Firefox +++ b/Extensions/Firefox @@ -1 +1 @@ -Subproject commit e2b2ec7b4e0b2dbcee788f55f14bc8212629bc6c +Subproject commit b5648592d159bb96343412a060d46143088f9bf0 diff --git a/src/components/AddDownloadsModal.tsx b/src/components/AddDownloadsModal.tsx index 3778e3c..9ca75d7 100644 --- a/src/components/AddDownloadsModal.tsx +++ b/src/components/AddDownloadsModal.tsx @@ -48,6 +48,14 @@ const isCrossHostRedirect = (sourceUrl: string, downloadUrl: string) => { } }; +const normalizeComparableUrl = (rawUrl: string) => { + try { + return new URL(rawUrl).href; + } catch { + return rawUrl.trim(); + } +}; + export const AddDownloadsModal = () => { const { addToast } = useToast(); const { @@ -97,6 +105,7 @@ export const AddDownloadsModal = () => { const [checksumValue, setChecksumValue] = useState(''); const [headers, setHeaders] = useState(''); const [cookies, setCookies] = useState(''); + const headersFromExtensionRef = useRef(false); const cookiesFromExtensionRef = useRef(false); const [mirrors, setMirrors] = useState(''); @@ -119,10 +128,12 @@ export const AddDownloadsModal = () => { setChecksumEnabled(false); setChecksumAlgo('SHA-256'); setChecksumValue(''); - setHeaders([ + const extensionHeaders = [ pendingAddReferer ? `Referer: ${pendingAddReferer.replace(/[\r\n]/g, '')}` : '', pendingAddHeaders - ].filter(Boolean).join('\n')); + ].filter(Boolean).join('\n'); + setHeaders(extensionHeaders); + headersFromExtensionRef.current = Boolean(extensionHeaders.trim()); setCookies(pendingAddCookies); cookiesFromExtensionRef.current = Boolean(pendingAddCookies?.trim()); setMirrors(''); @@ -211,7 +222,7 @@ export const AddDownloadsModal = () => { } } - const mediaData = await fetchMediaMetadataDeduped({ + const mediaMetadataArgs = { url: row.sourceUrl, cookieBrowser: browserArg, userAgent: settingsStore.customUserAgent.trim() || null, @@ -220,7 +231,58 @@ export const AddDownloadsModal = () => { headers: headers?.trim() || null, cookies: cookies?.trim() || null, proxy - }); + }; + const cleanMediaMetadataArgs = { + ...mediaMetadataArgs, + headers: null, + cookies: null + }; + const isExtensionMediaRow = pendingAddMediaUrls + .map(normalizeComparableUrl) + .includes(normalizeComparableUrl(row.sourceUrl)); + const hasExtensionContext = + headersFromExtensionRef.current || cookiesFromExtensionRef.current; + let mediaData; + if (isExtensionMediaRow && hasExtensionContext) { + try { + mediaData = await fetchMediaMetadataDeduped(cleanMediaMetadataArgs); + if (headersFromExtensionRef.current) { + setHeaders(''); + headersFromExtensionRef.current = false; + } + if (cookiesFromExtensionRef.current) { + setCookies(''); + cookiesFromExtensionRef.current = false; + } + } catch (cleanError) { + console.warn( + 'Media metadata failed without extension browser context; retrying with extension headers/cookies', + cleanError + ); + mediaData = await fetchMediaMetadataDeduped(mediaMetadataArgs); + } + } else { + try { + mediaData = await fetchMediaMetadataDeduped(mediaMetadataArgs); + } catch (error) { + if (!hasExtensionContext) { + throw error; + } + console.warn( + 'Media metadata failed with extension browser context; retrying without extension headers/cookies', + error + ); + mediaData = await fetchMediaMetadataDeduped(cleanMediaMetadataArgs); + if (headersFromExtensionRef.current) { + setHeaders(''); + headersFromExtensionRef.current = false; + } + if (cookiesFromExtensionRef.current) { + setCookies(''); + cookiesFromExtensionRef.current = false; + } + } + } if (mediaData && mediaData.formats.length > 0) { const mappedFormats = mediaData.formats.map(f => { const quality = f.resolution || 'Video'; @@ -1036,7 +1098,15 @@ export const AddDownloadsModal = () => {
-