1+ /**
2+ * M3U8 代理请求头测试脚本
3+ * 测试 Windows 11 User-Agent 和自定义请求头的传递
4+ */
5+
6+ import fetch from 'node-fetch' ;
7+
8+ const PROXY_BASE = 'http://localhost:3002' ;
9+ const AUTH_CODE = 'drpys' ;
10+ const TEST_URL = 'https://vip.ffzy-play8.com/20250610/713568_ef2eb646/index.m3u8' ;
11+
12+ // Windows 11 Chrome User-Agent
13+ const WIN11_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' ;
14+
15+ /**
16+ * 构建代理 URL
17+ */
18+ function buildProxyUrl ( targetUrl , customHeaders = null ) {
19+ const encodedUrl = encodeURIComponent ( targetUrl ) ;
20+ let proxyUrl = `${ PROXY_BASE } /m3u8-proxy/proxy?url=${ encodedUrl } &auth=${ AUTH_CODE } ` ;
21+
22+ if ( customHeaders ) {
23+ const encodedHeaders = encodeURIComponent ( JSON . stringify ( customHeaders ) ) ;
24+ proxyUrl += `&headers=${ encodedHeaders } ` ;
25+ }
26+
27+ return proxyUrl ;
28+ }
29+
30+ /**
31+ * 测试默认 User-Agent(无自定义请求头)
32+ */
33+ async function testDefaultUserAgent ( ) {
34+ console . log ( '\n🎯 测试 1: 默认 User-Agent(无自定义请求头)' ) ;
35+ console . log ( '============================================================' ) ;
36+
37+ const proxyUrl = buildProxyUrl ( TEST_URL ) ;
38+ console . log ( `📡 代理 URL: ${ proxyUrl } ` ) ;
39+
40+ try {
41+ const response = await fetch ( proxyUrl , { method : 'GET' } ) ;
42+ const content = await response . text ( ) ;
43+
44+ console . log ( `✅ 响应状态: ${ response . status } ${ response . statusText } ` ) ;
45+ console . log ( `📋 Content-Type: ${ response . headers . get ( 'content-type' ) } ` ) ;
46+ console . log ( `📄 内容长度: ${ content . length } 字符` ) ;
47+
48+ // 检查是否包含代理链接
49+ const hasProxyLinks = content . includes ( '/m3u8-proxy/proxy' ) ;
50+ console . log ( `🔗 包含代理链接: ${ hasProxyLinks ? '✅ 是' : '❌ 否' } ` ) ;
51+
52+ // 检查嵌套链接是否包含 headers 参数
53+ const hasHeadersParam = content . includes ( '&headers=' ) ;
54+ console . log ( `📋 嵌套链接包含 headers 参数: ${ hasHeadersParam ? '✅ 是' : '❌ 否' } ` ) ;
55+
56+ return response . status === 200 ;
57+ } catch ( error ) {
58+ console . error ( `❌ 测试失败: ${ error . message } ` ) ;
59+ return false ;
60+ }
61+ }
62+
63+ /**
64+ * 测试自定义 Windows 11 User-Agent
65+ */
66+ async function testCustomUserAgent ( ) {
67+ console . log ( '\n🎯 测试 2: 自定义 Windows 11 User-Agent' ) ;
68+ console . log ( '============================================================' ) ;
69+
70+ const customHeaders = {
71+ 'User-Agent' : WIN11_USER_AGENT ,
72+ 'Accept' : 'application/vnd.apple.mpegurl, application/x-mpegURL, application/octet-stream' ,
73+ 'Accept-Language' : 'zh-CN,zh;q=0.9,en;q=0.8' ,
74+ 'Referer' : 'https://example.com/'
75+ } ;
76+
77+ const proxyUrl = buildProxyUrl ( TEST_URL , customHeaders ) ;
78+ console . log ( `📡 代理 URL: ${ proxyUrl } ` ) ;
79+ console . log ( `🖥️ User-Agent: ${ customHeaders [ 'User-Agent' ] } ` ) ;
80+
81+ try {
82+ const response = await fetch ( proxyUrl , { method : 'GET' } ) ;
83+ const content = await response . text ( ) ;
84+
85+ console . log ( `✅ 响应状态: ${ response . status } ${ response . statusText } ` ) ;
86+ console . log ( `📋 Content-Type: ${ response . headers . get ( 'content-type' ) } ` ) ;
87+ console . log ( `📄 内容长度: ${ content . length } 字符` ) ;
88+
89+ // 检查是否包含代理链接
90+ const hasProxyLinks = content . includes ( '/m3u8-proxy/proxy' ) ;
91+ console . log ( `🔗 包含代理链接: ${ hasProxyLinks ? '✅ 是' : '❌ 否' } ` ) ;
92+
93+ // 检查嵌套链接是否包含 headers 参数
94+ const hasHeadersParam = content . includes ( '&headers=' ) ;
95+ console . log ( `📋 嵌套链接包含 headers 参数: ${ hasHeadersParam ? '✅ 是' : '❌ 否' } ` ) ;
96+
97+ // 显示处理后的内容
98+ console . log ( '\n📄 处理后的 M3U8 内容:' ) ;
99+ console . log ( '------------------------------------------------------------' ) ;
100+ console . log ( content ) ;
101+ console . log ( '------------------------------------------------------------' ) ;
102+
103+ return response . status === 200 && hasHeadersParam ;
104+ } catch ( error ) {
105+ console . error ( `❌ 测试失败: ${ error . message } ` ) ;
106+ return false ;
107+ }
108+ }
109+
110+ /**
111+ * 测试 HEAD 请求与自定义请求头
112+ */
113+ async function testHeadWithCustomHeaders ( ) {
114+ console . log ( '\n🎯 测试 3: HEAD 请求与自定义请求头' ) ;
115+ console . log ( '============================================================' ) ;
116+
117+ const customHeaders = {
118+ 'User-Agent' : WIN11_USER_AGENT ,
119+ 'Accept' : '*/*' ,
120+ 'Accept-Encoding' : 'gzip, deflate, br'
121+ } ;
122+
123+ const proxyUrl = buildProxyUrl ( TEST_URL , customHeaders ) ;
124+ console . log ( `📡 代理 URL: ${ proxyUrl } ` ) ;
125+ console . log ( `🖥️ User-Agent: ${ customHeaders [ 'User-Agent' ] } ` ) ;
126+
127+ try {
128+ const response = await fetch ( proxyUrl , { method : 'HEAD' } ) ;
129+
130+ console . log ( `✅ 响应状态: ${ response . status } ${ response . statusText } ` ) ;
131+ console . log ( `📋 Content-Type: ${ response . headers . get ( 'content-type' ) } ` ) ;
132+ console . log ( `📏 Content-Length: ${ response . headers . get ( 'content-length' ) || '未设置' } ` ) ;
133+ console . log ( `🔄 CORS 头: ${ response . headers . get ( 'access-control-allow-origin' ) } ` ) ;
134+
135+ return response . status === 200 ;
136+ } catch ( error ) {
137+ console . error ( `❌ HEAD 请求失败: ${ error . message } ` ) ;
138+ return false ;
139+ }
140+ }
141+
142+ /**
143+ * 测试嵌套 M3U8 文件的请求头传递
144+ */
145+ async function testNestedM3u8Headers ( ) {
146+ console . log ( '\n🎯 测试 4: 嵌套 M3U8 文件的请求头传递' ) ;
147+ console . log ( '============================================================' ) ;
148+
149+ const customHeaders = {
150+ 'User-Agent' : WIN11_USER_AGENT ,
151+ 'Accept' : 'application/vnd.apple.mpegurl' ,
152+ 'X-Custom-Header' : 'test-value-123'
153+ } ;
154+
155+ // 首先获取主 M3U8 文件
156+ const mainProxyUrl = buildProxyUrl ( TEST_URL , customHeaders ) ;
157+ console . log ( `📡 主 M3U8 代理 URL: ${ mainProxyUrl } ` ) ;
158+
159+ try {
160+ const mainResponse = await fetch ( mainProxyUrl , { method : 'GET' } ) ;
161+ const mainContent = await mainResponse . text ( ) ;
162+
163+ console . log ( `✅ 主 M3U8 响应状态: ${ mainResponse . status } ${ mainResponse . statusText } ` ) ;
164+
165+ // 提取第一个嵌套的代理链接
166+ const lines = mainContent . split ( '\n' ) ;
167+ let nestedProxyUrl = null ;
168+
169+ for ( const line of lines ) {
170+ if ( line . trim ( ) . startsWith ( 'http://localhost:3002/m3u8-proxy/proxy' ) ) {
171+ nestedProxyUrl = line . trim ( ) ;
172+ break ;
173+ }
174+ }
175+
176+ if ( ! nestedProxyUrl ) {
177+ console . log ( '❌ 未找到嵌套的代理链接' ) ;
178+ return false ;
179+ }
180+
181+ console . log ( `📡 嵌套代理 URL: ${ nestedProxyUrl } ` ) ;
182+
183+ // 检查嵌套链接是否包含 headers 参数
184+ const hasHeadersParam = nestedProxyUrl . includes ( '&headers=' ) ;
185+ console . log ( `📋 嵌套链接包含 headers 参数: ${ hasHeadersParam ? '✅ 是' : '❌ 否' } ` ) ;
186+
187+ if ( hasHeadersParam ) {
188+ // 解码 headers 参数
189+ const urlObj = new URL ( nestedProxyUrl ) ;
190+ const headersParam = urlObj . searchParams . get ( 'headers' ) ;
191+ if ( headersParam ) {
192+ try {
193+ const decodedHeaders = JSON . parse ( decodeURIComponent ( headersParam ) ) ;
194+ console . log ( '📋 解码后的请求头:' , JSON . stringify ( decodedHeaders , null , 2 ) ) ;
195+
196+ // 验证自定义请求头是否正确传递
197+ const hasCustomHeader = decodedHeaders [ 'X-Custom-Header' ] === 'test-value-123' ;
198+ const hasUserAgent = decodedHeaders [ 'User-Agent' ] === WIN11_USER_AGENT ;
199+
200+ console . log ( `🔍 自定义请求头传递: ${ hasCustomHeader ? '✅ 正确' : '❌ 错误' } ` ) ;
201+ console . log ( `🖥️ User-Agent 传递: ${ hasUserAgent ? '✅ 正确' : '❌ 错误' } ` ) ;
202+
203+ return hasCustomHeader && hasUserAgent ;
204+ } catch ( e ) {
205+ console . log ( '❌ 解码 headers 参数失败:' , e . message ) ;
206+ return false ;
207+ }
208+ }
209+ }
210+
211+ return hasHeadersParam ;
212+ } catch ( error ) {
213+ console . error ( `❌ 嵌套测试失败: ${ error . message } ` ) ;
214+ return false ;
215+ }
216+ }
217+
218+ /**
219+ * 运行所有测试
220+ */
221+ async function runAllTests ( ) {
222+ console . log ( '🚀 开始 M3U8 代理请求头测试' ) ;
223+ console . log ( `🎬 测试 URL: ${ TEST_URL } ` ) ;
224+ console . log ( `🖥️ Windows 11 User-Agent: ${ WIN11_USER_AGENT } ` ) ;
225+
226+ const results = {
227+ defaultUserAgent : await testDefaultUserAgent ( ) ,
228+ customUserAgent : await testCustomUserAgent ( ) ,
229+ headWithHeaders : await testHeadWithCustomHeaders ( ) ,
230+ nestedHeaders : await testNestedM3u8Headers ( )
231+ } ;
232+
233+ console . log ( '\n📊 测试结果总结' ) ;
234+ console . log ( '============================================================' ) ;
235+ console . log ( `默认 User-Agent 测试: ${ results . defaultUserAgent ? '✅ 通过' : '❌ 失败' } ` ) ;
236+ console . log ( `自定义 User-Agent 测试: ${ results . customUserAgent ? '✅ 通过' : '❌ 失败' } ` ) ;
237+ console . log ( `HEAD 请求头测试: ${ results . headWithHeaders ? '✅ 通过' : '❌ 失败' } ` ) ;
238+ console . log ( `嵌套请求头传递测试: ${ results . nestedHeaders ? '✅ 通过' : '❌ 失败' } ` ) ;
239+
240+ const allPassed = Object . values ( results ) . every ( result => result ) ;
241+ console . log ( `\n🎯 总体结果: ${ allPassed ? '🎉 全部通过' : '⚠️ 部分失败' } ` ) ;
242+
243+ return allPassed ;
244+ }
245+
246+ runAllTests ( ) . catch ( console . error ) ;
0 commit comments