Skip to content
This repository was archived by the owner on Dec 15, 2025. It is now read-only.

Commit 91c0646

Browse files
committed
after fix
1 parent 0d43ad1 commit 91c0646

File tree

2 files changed

+74
-18
lines changed

2 files changed

+74
-18
lines changed

src/proxy.js

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,38 @@ function processM3U8Content(content, mediaUrl, origin, headers) {
99
const uriMatch = line.match(/(URI=)(["'])(?<uri>.*?)\2/);
1010
if (uriMatch) {
1111
const [fullMatch, prefix, quote] = uriMatch;
12-
console.log(fullMatch, prefix, quote);
12+
try {
13+
const resolvedUrl = new URL(uriMatch.groups.uri, mediaUrl).toString();
14+
const proxyUrl = `${origin}/proxy?url=${encodeURIComponent(resolvedUrl)}${_headers}`;
15+
return line.replace(fullMatch, `${prefix}${quote}${proxyUrl}${quote}`);
16+
} catch (error) {
17+
console.error('Error processing URI:', uriMatch.groups.uri, error);
18+
return line;
19+
}
20+
}
1321

14-
const resolvedUrl = new URL(uriMatch.groups.uri, mediaUrl).toString();
15-
const proxyUrl = `${origin}/proxy?url=${encodeURIComponent(resolvedUrl)}${_headers}`;
16-
return line.replace(fullMatch, `${prefix}${quote}${proxyUrl}${quote}`);
22+
if (line.startsWith('#EXT-X-STREAM-INF')) {
23+
return line;
1724
}
1825

1926
if (!line.startsWith('#') && line.trim()) {
20-
const resolvedUrl = new URL(line.trim(), mediaUrl).toString();
21-
const proxyUrl = `${origin}/proxy?url=${encodeURIComponent(resolvedUrl)}${_headers}`;
22-
return line.replace(line.trim(), proxyUrl);
27+
try {
28+
const resolvedUrl = new URL(line.trim(), mediaUrl).toString();
29+
const proxyUrl = `${origin}/proxy?url=${encodeURIComponent(resolvedUrl)}${_headers}`;
30+
return proxyUrl;
31+
} catch (error) {
32+
console.error('Error processing URL:', line.trim(), error);
33+
return line;
34+
}
2335
}
2436

2537
return line;
2638
})
2739
.join('\n');
2840
}
41+
2942
async function proxy(request) {
43+
// console.log(`Processing ${request.method} request for: ${request.url}`);
3044
if (request.method === 'OPTIONS') {
3145
return new Response(null, {
3246
status: 204,
@@ -53,41 +67,84 @@ async function proxy(request) {
5367
if (rangeHeader) {
5468
fetchHeaders['Range'] = rangeHeader;
5569
}
70+
5671
const response = await fetch(mediaUrl, {
5772
headers: fetchHeaders,
5873
});
5974

6075
if (!response.ok) {
6176
throw new Error(`HTTP error! status: ${response.status}`);
6277
}
78+
6379
const cleanHeaders = Object.fromEntries(
6480
Array.from(response.headers.entries()).filter(([key], i, arr) => arr.findIndex(([k]) => k.toLowerCase() === key.toLowerCase()) === i)
6581
);
82+
delete cleanHeaders['Access-Control-Allow-Origin'];
83+
delete cleanHeaders['access-control-allow-origin'];
84+
const responseHeaders = {
85+
...cleanHeaders,
86+
'Access-Control-Allow-Origin': '*',
87+
'Access-Control-Expose-Headers': Object.keys(cleanHeaders).join(', '),
88+
};
89+
90+
const contentType = response.headers.get('Content-Type') || '';
91+
92+
const urlIndication = mediaUrl.toLowerCase().includes('.m3u8') || mediaUrl.toLowerCase().includes('/playlist');
6693

6794
let responseContent = await response.text();
68-
if (!responseContent.trimStart().startsWith('#EXTM3U')) {
95+
const contentLooksLikeM3U8 = responseContent.trimStart().startsWith('#EXTM3U');
96+
97+
const isM3U8 =
98+
contentLooksLikeM3U8 ||
99+
contentType.includes('application/vnd.apple.mpegurl') ||
100+
contentType.includes('application/x-mpegurl') ||
101+
contentType.includes('audio/mpegurl') ||
102+
contentType.includes('audio/x-mpegurl');
103+
104+
if (isM3U8) {
105+
responseContent = processM3U8Content(responseContent, mediaUrl, origin, decodedHeaders);
106+
107+
responseHeaders['Content-Type'] = 'application/vnd.apple.mpegurl';
69108
return new Response(responseContent, {
70109
status: response.status,
71-
headers: {
72-
...cleanHeaders,
73-
'Access-Control-Allow-Origin': '*',
74-
},
110+
headers: responseHeaders,
75111
});
76112
}
77-
responseContent = processM3U8Content(responseContent, mediaUrl, origin, decodedHeaders);
113+
114+
if (!contentLooksLikeM3U8 && responseContent.length > 0) {
115+
const hasManyNonPrintable =
116+
responseContent.split('').filter((char) => char.charCodeAt(0) < 32 && char !== '\n' && char !== '\r' && char !== '\t').length >
117+
responseContent.length * 0.1;
118+
119+
if (
120+
hasManyNonPrintable ||
121+
contentType.includes('video/') ||
122+
contentType.includes('audio/') ||
123+
contentType.includes('image/') ||
124+
contentType.includes('application/octet-stream')
125+
) {
126+
const binaryResponse = await fetch(mediaUrl, {
127+
headers: fetchHeaders,
128+
});
129+
const arrayBuffer = await binaryResponse.arrayBuffer();
130+
return new Response(arrayBuffer, {
131+
status: binaryResponse.status,
132+
headers: responseHeaders,
133+
});
134+
}
135+
}
78136

79137
return new Response(responseContent, {
80-
headers: {
81-
...cleanHeaders,
82-
'Access-Control-Allow-Origin': '*',
83-
},
138+
status: response.status,
139+
headers: responseHeaders,
84140
});
85141
} catch (error) {
86142
console.error('Error in proxy:', error);
87143
return new Response(`Proxy error: ${error.message}`, {
88144
status: 500,
89145
headers: {
90146
'Access-Control-Allow-Origin': '*',
147+
'Content-Type': 'text/plain',
91148
},
92149
});
93150
}

utils/handler.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export const decodeHeaders = (base64OrUrlEncodedHeaders) => {
88
let decodedString = base64OrUrlEncodedHeaders;
99

1010
const isBase64 = /^[A-Za-z0-9+/=]+$/.test(base64OrUrlEncodedHeaders) && base64OrUrlEncodedHeaders.length % 4 === 0;
11-
1211
try {
1312
if (isBase64) {
1413
decodedString = atob(base64OrUrlEncodedHeaders);

0 commit comments

Comments
 (0)