mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(desktop): fetch media bytes via the local resource proxy (#3263)
This commit is contained in:
1 parent
8b312c610e
commit
6a24ac3f4e
4 files changed
+66
-4
No files matched your search
+59
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
||||
|
||||
const runtime = vi.hoisted(() => ({desktop: false}));
|
||||
|
||||
vi.mock('@lingui/core/macro', () => ({msg: (descriptor: unknown) => descriptor}));
|
||||
|
||||
vi.mock('@app/features/platform/DesktopLocalAppRuntime', async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import('@app/features/platform/DesktopLocalAppRuntime')>()),
|
||||
isDesktopLocalAppDocument: () => runtime.desktop,
|
||||
}));
|
||||
vi.mock('@app/features/app/state/RuntimeConfig', () => ({
|
||||
default: {
|
||||
mediaEndpoint: 'https://fluxerusercontent.com',
|
||||
staticCdnEndpoint: 'https://fluxerstatic.com',
|
||||
uploadRelayEndpoint: null,
|
||||
getSnapshot: () => ({apiEndpoint: 'https://api.fluxer.app'}),
|
||||
},
|
||||
}));
|
||||
vi.mock('@app/features/app/state/InstanceSnapshotStore', () => ({runtimeInstanceKey: () => 'instance-key'}));
|
||||
vi.mock('@app/features/messaging/state/AttachmentUrlRefresher', () => ({
|
||||
default: {refresh: async (url: string) => url},
|
||||
}));
|
||||
|
||||
const {fetchTextualPreviewText} = await import(
|
||||
'@app/features/channel/components/embeds/attachments/TextualAttachmentPreviewFetch'
|
||||
);
|
||||
|
||||
const ATTACHMENT_URL = 'https://fluxerusercontent.com/attachments/1/2/message.txt?ex=1&is=2&hm=3';
|
||||
|
||||
describe('fetchTextualPreviewText', () => {
|
||||
const fetchMock = vi.fn(async (_input: RequestInfo | URL, _init?: RequestInit) => new Response('hello'));
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal('fetch', fetchMock);
|
||||
vi.stubGlobal('window', {location: {href: 'fluxer-app://app/channels/@me'}});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
fetchMock.mockClear();
|
||||
runtime.desktop = false;
|
||||
});
|
||||
|
||||
it('routes media fetches through the desktop resource proxy', async () => {
|
||||
runtime.desktop = true;
|
||||
await expect(fetchTextualPreviewText(ATTACHMENT_URL, new AbortController().signal)).resolves.toBe('hello');
|
||||
const requested = new URL(String(fetchMock.mock.calls[0]?.[0]));
|
||||
expect(requested.protocol).toBe('fluxer-app:');
|
||||
expect(requested.pathname).toBe('/proxy/instance-key');
|
||||
expect(requested.searchParams.get('url')).toBe(ATTACHMENT_URL);
|
||||
});
|
||||
|
||||
it('fetches media directly on the web', async () => {
|
||||
await expect(fetchTextualPreviewText(ATTACHMENT_URL, new AbortController().signal)).resolves.toBe('hello');
|
||||
expect(fetchMock.mock.calls[0]?.[0]).toBe(ATTACHMENT_URL);
|
||||
});
|
||||
});
|
||||
+3
-2
@@ -2,6 +2,7 @@
|
||||
|
||||
import AttachmentUrlRefresher from '@app/features/messaging/state/AttachmentUrlRefresher';
|
||||
import {TEXT_PREVIEW_MAX_BYTES} from '@app/features/messaging/utils/AttachmentPreviewUtils';
|
||||
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
|
||||
|
||||
const SIGNATURE_REFUSAL_STATUSES = new Set([401, 403, 404, 410]);
|
||||
|
||||
@@ -65,7 +66,7 @@ function requestFailed(response: Response): Error {
|
||||
|
||||
export async function fetchTextualPreviewText(url: string, signal: AbortSignal): Promise<string> {
|
||||
const target = await AttachmentUrlRefresher.refresh(url);
|
||||
const response = await fetch(target, {signal});
|
||||
const response = await fetch(wrapDesktopLocalResourceURL(target), {signal});
|
||||
if (response.ok) {
|
||||
return readPreviewText(response);
|
||||
}
|
||||
@@ -76,7 +77,7 @@ export async function fetchTextualPreviewText(url: string, signal: AbortSignal):
|
||||
if (refreshed === target) {
|
||||
throw requestFailed(response);
|
||||
}
|
||||
const retried = await fetch(refreshed, {signal});
|
||||
const retried = await fetch(wrapDesktopLocalResourceURL(refreshed), {signal});
|
||||
if (!retried.ok) {
|
||||
throw requestFailed(retried);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import type {Gif} from '@app/features/expressions/commands/GifCommands';
|
||||
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
|
||||
|
||||
const GIF_IMAGE_FORMAT_KEYS = ['gif', 'tinygif', 'nanogif'] as const;
|
||||
const GIF_VIDEO_FORMAT_KEYS = ['mp4', 'tinymp4'] as const;
|
||||
@@ -60,7 +61,7 @@ async function downloadFirstAvailableTarget(targets: Array<GifDownloadTarget>, b
|
||||
seenUrls.add(target.url);
|
||||
attempts += 1;
|
||||
try {
|
||||
const response = await fetch(target.url);
|
||||
const response = await fetch(wrapDesktopLocalResourceURL(target.url));
|
||||
if (!response.ok) continue;
|
||||
const blob = await response.blob();
|
||||
if (blob.size === 0) continue;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import {wrapDesktopLocalResourceURL} from '@app/features/messaging/utils/DesktopResourceUrl';
|
||||
import {Logger} from '@app/features/platform/utils/AppLogger';
|
||||
import StreamerMode from '@app/features/streamer_mode/state/StreamerMode';
|
||||
import Sound from '@app/features/ui/state/Sound';
|
||||
@@ -66,7 +67,7 @@ class EntranceSoundPlaybackEngine {
|
||||
const ctx = this.ensureContext();
|
||||
if (!ctx) return null;
|
||||
try {
|
||||
const response = await fetch(url, {cache: 'force-cache'});
|
||||
const response = await fetch(wrapDesktopLocalResourceURL(url), {cache: 'force-cache'});
|
||||
if (!response.ok) {
|
||||
logger.warn('Entrance sound fetch failed', {url, status: response.status});
|
||||
return null;
|
||||
|
||||
Reference in new issue
Block a user