forked from antebrl/IPTV-Restream
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProxyController.js
More file actions
125 lines (103 loc) · 4.41 KB
/
ProxyController.js
File metadata and controls
125 lines (103 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const request = require('request');
const url = require('url');
const ChannelService = require('../services/ChannelService');
const ProxyHelperService = require('../services/proxy/ProxyHelperService');
const SessionFactory = require('../services/session/SessionFactory');
const proxyBaseUrl = '/proxy/';
module.exports = {
async channel(req, res) {
let { url: targetUrl, channelId, headers } = req.query;
if(!targetUrl) {
const channel = channelId ?
ChannelService.getChannelById(parseInt(channelId)) :
ChannelService.getCurrentChannel();
if (!channel) {
res.status(404).json({ error: 'Channel not found' });
return;
}
targetUrl = channel.url;
const sessionProvider = SessionFactory.getSessionProvider(channel);
if(sessionProvider) {
await sessionProvider.createSession();
targetUrl = channel.sessionUrl;
}
if(channel.headers && channel.headers.length > 0) {
headers = Buffer.from(JSON.stringify(channel.headers)).toString('base64');
}
}
console.log('Proxy playlist request to:', targetUrl);
res.set('Access-Control-Allow-Origin', '*');
try {
request({
...ProxyHelperService.getRequestOptions(targetUrl, headers),
followRedirect: false
}, (error, response, body) => {
if (error) {
if (!res.headersSent) {
return res.status(500).json({ error: 'Failed to fetch m3u8 file' });
}
console.error('Request error:', error);
return;
}
// invalid response
if (response.statusCode >= 400) {
if (!res.headersSent) {
res.status(response.statusCode);
}
return res.send(body);
}
//redirect response
if (response.statusCode >= 300) {
const redirectLocation = response.headers.location;
const absoluteUrl = url.resolve(targetUrl, redirectLocation);
const proxyRedirect = `channel/?url=${encodeURIComponent(absoluteUrl)}${headers ? `&headers=${headers}` : ''}`;
return res.redirect(response.statusCode, proxyRedirect);
}
try {
const responseUrl = response.request.href;
const rewrittenBody = ProxyHelperService.rewriteUrls(body, proxyBaseUrl, headers, responseUrl).join('\n');
res.send(rewrittenBody);
} catch (e) {
console.error('Failed to rewrite URLs:', e);
res.status(500).json({ error: 'Failed to parse m3uo file. Not a valid HLS stream.' });
}
//res.set('Content-Type', 'application/vnd.apple.mpegurl');
}).on('error', (err) => {
console.error('Unhandled error:', err);
if (!res.headersSent) {
res.status(500).json({ error: 'Proxy request failed' });
}
});
} catch (e) {
console.error('Failed to proxy request:', e);
if (!res.headersSent) {
res.status(500).json({ error: 'Proxy request failed' });
}
}
},
segment(req, res) {
let { url: targetUrl, headers } = req.query;
if (!targetUrl) {
res.status(400).json({ error: 'Missing url query parameter' });
return;
}
console.log('Proxy request to:', targetUrl);
res.set('Access-Control-Allow-Origin', '*');
req.pipe(
request(ProxyHelperService.getRequestOptions(targetUrl, headers))
.on('error', (err) => {
console.error('Proxy request error:', err);
if (!res.headersSent) {
res.status(500).json({ error: 'Proxy request failed' });
}
return;
})
).pipe(res)
.on('error', (err) => {
console.error('Response stream error:', err);
});
},
key(req, res) {
module.exports.segment(req, res);
}
};