Auto-proxy Dropbox and HTTP media stream URLs at runtime
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// Maintainer-controlled web client version.
|
// Maintainer-controlled web client version.
|
||||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||||
window.CHGRID_WEB_VERSION = "2026.02.22 R139";
|
window.CHGRID_WEB_VERSION = "2026.02.22 R140";
|
||||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { resolveSpatialMix } from './spatial';
|
|||||||
|
|
||||||
export const RADIO_CHANNEL_OPTIONS = ['stereo', 'mono', 'left', 'right'] as const;
|
export const RADIO_CHANNEL_OPTIONS = ['stereo', 'mono', 'left', 'right'] as const;
|
||||||
export type RadioChannelMode = (typeof RADIO_CHANNEL_OPTIONS)[number];
|
export type RadioChannelMode = (typeof RADIO_CHANNEL_OPTIONS)[number];
|
||||||
|
const APP_BASE_PATH = import.meta.env.BASE_URL ?? '/';
|
||||||
|
|
||||||
type SharedRadioSource = {
|
type SharedRadioSource = {
|
||||||
streamUrl: string;
|
streamUrl: string;
|
||||||
@@ -108,18 +109,48 @@ function connectRadioChannelSource(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function freshStreamUrl(streamUrl: string): string {
|
function isDropboxHost(hostname: string): boolean {
|
||||||
|
const host = hostname.toLowerCase();
|
||||||
|
return host.endsWith('dropbox.com') || host.endsWith('dropboxusercontent.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldProxyStreamUrl(streamUrl: string): boolean {
|
||||||
try {
|
try {
|
||||||
const parsed = new URL(streamUrl);
|
const parsed = new URL(streamUrl);
|
||||||
|
if (
|
||||||
|
parsed.origin === window.location.origin &&
|
||||||
|
parsed.pathname.toLowerCase().endsWith('/media_proxy.php')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (parsed.protocol === 'http:') return true;
|
||||||
|
if (parsed.protocol === 'https:' && isDropboxHost(parsed.hostname)) return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProxyUrlForStream(streamUrl: string): string {
|
||||||
|
const normalizedBase = APP_BASE_PATH.endsWith('/') ? APP_BASE_PATH : `${APP_BASE_PATH}/`;
|
||||||
|
const proxy = new URL(`${normalizedBase}media_proxy.php`, window.location.origin);
|
||||||
|
proxy.searchParams.set('url', streamUrl);
|
||||||
|
return proxy.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function freshStreamUrl(streamUrl: string): string {
|
||||||
|
const playbackSource = shouldProxyStreamUrl(streamUrl) ? getProxyUrlForStream(streamUrl) : streamUrl;
|
||||||
|
try {
|
||||||
|
const parsed = new URL(playbackSource);
|
||||||
const hostname = parsed.hostname.toLowerCase();
|
const hostname = parsed.hostname.toLowerCase();
|
||||||
if (hostname.endsWith('dropbox.com') || hostname.endsWith('dropboxusercontent.com')) {
|
if (hostname.endsWith('dropbox.com') || hostname.endsWith('dropboxusercontent.com')) {
|
||||||
return streamUrl;
|
return playbackSource;
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Leave non-URL strings to the generic cache-buster behavior below.
|
// Leave non-URL strings to the generic cache-buster behavior below.
|
||||||
}
|
}
|
||||||
const separator = streamUrl.includes('?') ? '&' : '?';
|
const separator = playbackSource.includes('?') ? '&' : '?';
|
||||||
return `${streamUrl}${separator}chgrid_start=${Date.now()}`;
|
return `${playbackSource}${separator}chgrid_start=${Date.now()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
type RadioSpatialConfig = {
|
type RadioSpatialConfig = {
|
||||||
|
|||||||
Reference in New Issue
Block a user