chore: handle invalid MediaFlow Proxy password better

This commit is contained in:
WebStreamr 2025-06-25 18:16:12 +00:00
parent 3ac1063c9b
commit e895077a7b
No known key found for this signature in database
6 changed files with 54 additions and 5 deletions

View file

@ -23,6 +23,7 @@ export enum CountryCode {
export enum BlockedReason {
cloudflare_challenge = 'cloudflare_challenge',
flaresolverr_failed = 'flaresolverr_failed',
media_flow_proxy_auth = 'media_flow_proxy_auth',
unknown = 'unknown',
}

View file

@ -4,6 +4,7 @@ import fetchMock from 'fetch-mock';
import { Fetcher } from './Fetcher';
import { BlockedError, HttpError, NotFoundError, QueueIsFullError, TimeoutError, TooManyRequestsError, TooManyTimeoutsError } from '../error';
import { createTestContext } from '../test';
import { BlockedReason } from '../types';
fetchMock.mockGlobal();
const fetcher = new Fetcher(winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] }));
@ -88,7 +89,7 @@ describe('fetch', () => {
fail();
} catch (error) {
expect(error).toBeInstanceOf(BlockedError);
expect(error).toMatchObject({ reason: 'cloudflare_challenge' });
expect(error).toMatchObject({ reason: BlockedReason.cloudflare_challenge });
}
});
@ -137,7 +138,7 @@ describe('fetch', () => {
fail();
} catch (error) {
expect(error).toBeInstanceOf(BlockedError);
expect(error).toMatchObject({ reason: 'flaresolverr_failed' });
expect(error).toMatchObject({ reason: BlockedReason.flaresolverr_failed });
}
delete process.env['FLARESOLVERR_ENDPOINT'];
@ -151,7 +152,19 @@ describe('fetch', () => {
fail();
} catch (error) {
expect(error).toBeInstanceOf(BlockedError);
expect(error).toMatchObject({ reason: 'unknown' });
expect(error).toMatchObject({ reason: BlockedReason.unknown });
}
});
test('converts MediaFlow Proxy forbidden to custom BlockedError', async () => {
fetchMock.get('https://media-flow-proxy-forbidden-url.test/', { status: 403 });
try {
await fetcher.text(createTestContext({ mediaFlowProxyUrl: 'https://media-flow-proxy-forbidden-url.test/' }), new URL('https://media-flow-proxy-forbidden-url.test/'));
fail();
} catch (error) {
expect(error).toBeInstanceOf(BlockedError);
expect(error).toMatchObject({ reason: BlockedReason.media_flow_proxy_auth });
}
});

View file

@ -174,6 +174,10 @@ export class Fetcher {
}
if (httpCacheItem.status === 403) {
if (ctx.config.mediaFlowProxyUrl && url.href.startsWith(ctx.config.mediaFlowProxyUrl)) {
throw new BlockedError(BlockedReason.media_flow_proxy_auth, httpCacheItem.policy.responseHeaders());
}
throw new BlockedError(BlockedReason.unknown, httpCacheItem.policy.responseHeaders());
}

View file

@ -101,6 +101,17 @@ describe('resolve', () => {
countryCode: CountryCode.de,
},
},
{
url: new URL('https://example.com'),
format: Format.unknown,
isExternal: true,
error: new BlockedError(BlockedReason.media_flow_proxy_auth, {}),
label: 'hoster.com',
sourceId: '',
meta: {
countryCode: CountryCode.de,
},
},
{
url: new URL('https://example.com'),
format: Format.unknown,

View file

@ -1,7 +1,7 @@
import { ContentType, Stream } from 'stremio-addon-sdk';
import winston from 'winston';
import bytes from 'bytes';
import { Context, Format, UrlResult } from '../types';
import { BlockedReason, Context, Format, UrlResult } from '../types';
import { Source } from '../source';
import {
BlockedError,
@ -167,8 +167,10 @@ export class StreamResolver {
private logErrorAndReturnNiceString(ctx: Context, source: string, error: unknown): string {
if (error instanceof BlockedError) {
if (error.reason === 'cloudflare_challenge') {
if (error.reason === BlockedReason.cloudflare_challenge) {
this.logger.warn(`${source}: Request was blocked via Cloudflare challenge.`, ctx);
} else if (error.reason === BlockedReason.media_flow_proxy_auth) {
return '⚠️ MediaFlow Proxy authentication failed. Please set the correct password.';
} else {
this.logger.warn(`${source}: Request was blocked, headers: ${JSON.stringify(error.headers)}.`, ctx);
}

View file

@ -19,6 +19,15 @@ exports[`resolve adds error info 1`] = `
"externalUrl": "http://localhost/",
"name": "WebStreamr 🇩🇪",
"title": "🔗 hoster.com
⚠️ MediaFlow Proxy authentication failed. Please set the correct password.",
},
{
"behaviorHints": {
"notWebReady": true,
},
"externalUrl": "http://localhost/",
"name": "WebStreamr 🇩🇪",
"title": "🔗 hoster.com
⚠️ Request was blocked.",
},
{
@ -98,6 +107,15 @@ exports[`resolve adds error info 2`] = `
"externalUrl": "https://example.com/",
"name": "WebStreamr 🇩🇪 ⚠️ external",
"title": "🔗 hoster.com
⚠️ MediaFlow Proxy authentication failed. Please set the correct password.",
},
{
"behaviorHints": {
"notWebReady": true,
},
"externalUrl": "https://example.com/",
"name": "WebStreamr 🇩🇪 ⚠️ external",
"title": "🔗 hoster.com
⚠️ Request was blocked.",
},
{