diff --git a/fluxer_app/src/features/platform/transport/RestTransport.test.ts b/fluxer_app/src/features/platform/transport/RestTransport.test.ts index 011787de7..0d407adcf 100644 --- a/fluxer_app/src/features/platform/transport/RestTransport.test.ts +++ b/fluxer_app/src/features/platform/transport/RestTransport.test.ts @@ -8,6 +8,17 @@ import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest'; vi.mock('@lingui/core/macro', () => ({msg: (descriptor: MessageDescriptor) => descriptor})); +const desktopDocument = vi.hoisted(() => ({active: false})); + +vi.mock('@app/features/platform/DesktopLocalAppRuntime', async (importOriginal) => { + const actual = await importOriginal(); + return {...actual, isDesktopLocalAppDocument: () => desktopDocument.active}; +}); + +vi.mock('@app/features/ui/utils/NativeUtils', () => ({ + getElectronAPI: () => (desktopDocument.active ? {localAppUpload: {subscribe: () => () => {}}} : undefined), +})); + interface SentRequest { method: string; url: string; @@ -95,6 +106,31 @@ beforeEach(() => { afterEach(() => { vi.unstubAllGlobals(); + desktopDocument.active = false; +}); + +describe('RestClient desktop local upload tagging', () => { + const uploadIdHeader = 'x-fluxer-local-upload-id'; + + test('a remote upload from the desktop app never carries the local upload id', async () => { + desktopDocument.active = true; + await createClient().put('https://uploads.fluxer.app/v1/relay/abc?t=token', { + body: new Blob(['x']), + auth: 'none', + onProgress: () => {}, + }); + expect(sent[0].headers[uploadIdHeader]).toBeUndefined(); + }); + + test('an upload through the desktop local proxy is tagged for progress', async () => { + desktopDocument.active = true; + await createClient().put('fluxer-app://app/_remote/key?url=https%3A%2F%2Fuploads.test%2Fv1%2Frelay%2Fabc', { + body: new Blob(['x']), + auth: 'none', + onProgress: () => {}, + }); + expect(sent[0].headers[uploadIdHeader]).toMatch(/^[0-9a-f]{32}$/u); + }); }); describe('RestClient interceptor selection', () => { diff --git a/fluxer_app/src/features/platform/transport/RestTransport.ts b/fluxer_app/src/features/platform/transport/RestTransport.ts index 0429e363d..1a4e7e173 100644 --- a/fluxer_app/src/features/platform/transport/RestTransport.ts +++ b/fluxer_app/src/features/platform/transport/RestTransport.ts @@ -715,8 +715,23 @@ function newLocalUploadId(): string { return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(''); } -function attachLocalUploadProgress(xhr: XMLHttpRequest, onProgress: (event: ProgressEvent) => void): boolean { - if (!isDesktopLocalAppDocument()) { +function isDesktopLocalAppRequest(url: string): boolean { + if (!isDesktopLocalAppDocument()) return false; + let parsedUrl: URL; + try { + parsedUrl = resolveDocumentURLFromRoot(url); + } catch { + return false; + } + return isDesktopLocalAppOrigin(parsedUrl.protocol, parsedUrl.hostname); +} + +function attachLocalUploadProgress( + xhr: XMLHttpRequest, + url: string, + onProgress: (event: ProgressEvent) => void, +): boolean { + if (!isDesktopLocalAppRequest(url)) { return false; } const subscribe = getElectronAPI()?.localAppUpload?.subscribe; @@ -768,7 +783,7 @@ function performTransport(plan: Plan, handle: RestRequestHandle): Promise