m3u8-monkey-script/src/parser/key-fetch.ts

44 lines
2 KiB
TypeScript

import { log } from '../logger';
import { normalizeReferer } from '../utils/uri';
export async function fetchKey(keyUri: string, referer?: string, origin?: string): Promise<Uint8Array> {
const fallbackReferer = document.location.href;
const fallbackOrigin = new URL(document.location.href).origin;
const effectiveReferer = normalizeReferer(keyUri, referer || fallbackReferer);
const effectiveOrigin = origin || (referer ? new URL(referer).origin : fallbackOrigin);
log.info(`fetchKey request: url=${keyUri} referer=${effectiveReferer} origin=${effectiveOrigin}`);
return new Promise((resolve, reject) => {
(GM_xmlhttpRequest as any)({
method: 'GET',
url: keyUri,
responseType: 'arraybuffer',
headers: {
'Referer': effectiveReferer,
'Origin': effectiveOrigin,
},
onload: (response: any) => {
log.info(`fetchKey response: status=${response.status} readyState=${response.readyState} headers=${JSON.stringify(response.responseHeaders)}`);
if (response.status >= 200 && response.status < 300) {
const buffer = response.detail?.response || response.response;
const keyBytes = new Uint8Array(buffer);
log.info(`fetchKey: ${keyUri} size=${keyBytes.length} bytes`);
if (keyBytes.length !== 16) {
log.warn(`fetchKey: key is ${keyBytes.length} bytes, expected 16 for AES-128`);
}
resolve(keyBytes);
} else {
log.error(`fetchKey HTTP error: status=${response.status} url=${keyUri} responseHeaders=${JSON.stringify(response.responseHeaders)}`);
reject(new Error(`Key fetch failed: HTTP ${response.status}`));
}
},
onerror: (error: any) => {
log.error(`fetchKey network error: url=${keyUri} error=${error.error} status=${error.status} readyState=${error.readyState} responseHeaders=${JSON.stringify(error.responseHeaders || {})}`);
reject(new Error(`Key fetch error: ${error.error}`));
},
});
});
}