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

Commit 9c0bcfa

Browse files
committed
Fixed issue with the Manga Images
1 parent 55ccf3c commit 9c0bcfa

File tree

3 files changed

+46
-22
lines changed

3 files changed

+46
-22
lines changed

README.md

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
1-
# HLS Stream Proxy
1+
## Cloudflare Proxy
22

3-
This application serves as a proxy for HLS streams, enabling secure access to media content.
3+
This application serves as a proxy for HLS streams, Images and enabling secure access to media content.
4+
5+
### Deploy Using Cloudflare deploy button
6+
7+
- Enter valid Cloudflare API key and Account ID.
8+
- Enable github workflows
9+
- Run **`deploy`** workflow in your forked repo actions `https://github.com/[User-Name]/[Repo-Name]/actions/workflows/deploy.yml`
10+
<br>
411

512
[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/Toasty360/Roxy)
613

7-
## Proxy Endpoint
14+
### Deploy Manually
15+
16+
- Setup wrangler on your system.
17+
- Download the source code.
18+
- Run `npm install`
19+
- Run `npm run dev` or `wrangler dev` in your terminal to start a development server
20+
- Open a browser tab at http://localhost:8787/ to see your worker in action
21+
- Run `wrangler deploy` to publish your worker
22+
23+
### Proxy Endpoint
24+
25+
- `/proxy` - for HLS
26+
- `/cors` - for Images/Web pages
827

928
Use the following format to access the proxy:
1029

@@ -17,23 +36,23 @@ Use the following format to access the proxy:
1736

1837
---
1938

20-
## Encoding Instructions
39+
### Encoding Instructions
2140

22-
### Encode M3U8 URL:
41+
#### Encode M3U8 URL:
2342

2443
```javascript
2544
btoa('http://example.com/stream.m3u8');
2645
```
2746

28-
### Encode Headers (if needed):
47+
#### Encode Headers (if needed):
2948

3049
```javascript
3150
btoa(JSON.stringify({ Referrer: 'https://anitaku.bz' }));
3251
```
3352

3453
---
3554

36-
## Example Request
55+
### Example Request
3756

3857
```
3958
/proxy?url=aHR0cDovL2V4YW1wbGUuY29tL3N0cmVhbS5tM3U4&headers=eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIHRva2VuIn0=

src/cors.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
// Function to decode base64 strings
2-
function atobPolyfill(encoded) {
3-
return decodeURIComponent(escape(globalThis.atob(encoded)));
4-
}
5-
61
async function handleCorsRequest(request) {
72
const urlParams = new URL(request.url).searchParams;
83
const encodedUrl = urlParams.get('url');
@@ -15,23 +10,33 @@ async function handleCorsRequest(request) {
1510
}
1611

1712
// Decode the base64-encoded URL
18-
const targetUrl = atobPolyfill(encodedUrl);
13+
let targetUrl;
14+
try {
15+
targetUrl = atob(encodedUrl);
16+
} catch (error) {
17+
return new Response('Failed to decode URL. Ensure it is base64-encoded.', {
18+
status: 400,
19+
});
20+
}
1921

2022
let decodedHeaders = {};
2123
if (headersBase64) {
2224
try {
23-
const decodedString = atobPolyfill(headersBase64);
25+
const decodedString = atob(headersBase64);
2426
decodedHeaders = JSON.parse(decodedString);
2527
} catch (error) {
26-
return new Response('Invalid headers format. Must be valid base64-encoded.', {
28+
return new Response('Invalid headers format. Must be valid base64-encoded JSON.', {
2729
status: 400,
2830
});
2931
}
3032
}
3133

3234
// Convert the plain JSON headers object to a Headers instance
33-
3435
const headers = new Headers();
36+
headers.append(
37+
'User-Agent',
38+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/237.84.2.178 Safari/537.36'
39+
);
3540
for (const [key, value] of Object.entries(decodedHeaders)) {
3641
headers.append(key, value);
3742
}
@@ -40,17 +45,15 @@ async function handleCorsRequest(request) {
4045
// Fetch the target URL with the specified headers
4146
const response = await fetch(targetUrl, {
4247
redirect: 'follow',
43-
headers: headers, // Use the Headers object here
48+
headers,
4449
});
4550

46-
const responseBody = await response.text();
47-
48-
// Return the response to the requester with proper CORS headers
49-
return new Response(responseBody, {
51+
// Stream the response body back to the client
52+
return new Response(response.body, {
5053
status: response.status,
5154
headers: {
5255
'Access-Control-Allow-Origin': '*', // Adjust based on your CORS policy
53-
'Content-Type': response.headers.get('Content-Type') || 'text/plain',
56+
'Content-Type': response.headers.get('Content-Type') || 'application/octet-stream',
5457
},
5558
});
5659
} catch (error) {

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export default {
2121
return proxy(request);
2222
} else if (url.pathname === '/cors') {
2323
return handleCorsRequest(request);
24+
} else if (url.pathname === '/image') {
25+
return handleCorsRequest(request);
2426
} else if (url.pathname === '/') {
2527
return new Response(
2628
JSON.stringify({

0 commit comments

Comments
 (0)